I have the 4-d array with shape (3,32,32,32)
of 1bit and I want to reduce it to (3,32,32)
with the elements becoming 32bit. The values in the array is 0s and 1s .The numbering in the array is just a way to visualize my question, it represents the nth
bit of the resulting segment of 32-bit that I want.
[[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]],
[[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
...,
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.]],
[[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
...,
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.]],
...,
[[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
...,
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.]],
[[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
...,
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.]],
[[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
...,
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.]]], #1
[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]],
[[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
...,
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.]],
[[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
...,
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.]],
...,
[[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
...,
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.]],
[[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
...,
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.]],
[[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
...,
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.]]], #2
[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]],
[[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
...,
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 1., 1., 1., ..., 1., 1., 1.]],
[[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
...,
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.],
[ 2., 2., 2., ..., 2., 2., 2.]],
...,
[[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
...,
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.],
[29., 29., 29., ..., 29., 29., 29.]],
[[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
...,
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.],
[30., 30., 30., ..., 30., 30., 30.]],
[[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
...,
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.],
[31., 31., 31., ..., 31., 31., 31.]]]] #3
Sorry if this is such an obvious question as I am still learning.
I want my resulting array to be of size (3,32,32)
with the following arrangements:
[[[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
...,
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31]], #1
[[[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
...,
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31]], #2
[[[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
...,
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31],
[bit0bit1bit2...bit30bit31, bit0bit1bit2...bit30bit31, ..., bit0bit1bit2...bit30bit31]]] #3
CodePudding user response:
The fastest way, I think (and also one of the shortest to write, tho not to understand if you are not used to this function) is probably using einsum
import numpy as np
# Just for the example, I build it backward
x = np.random.randint(0,2000000000, (3, 32, 32))
# So x is the result we expect to find.
# Let build the 3,32,32,32 array of 1/0
bits = np.stack([(x//(2**k))%2 for k in range(32)], axis=1)
# So now, what we want is to create x back from bits
# For that we need a array of multiplicators
coef = np.array([2**k for k in range(32)])
# And now the magic one liner
xx=np.einsum('ijkl,j', bits, coef)
# And the test to check if we found back x
np.abs(xx-x).max()
# 0
So, one-liner is np.einsum('ijkl,j', bits, [2**k for k in range(32)])
As used here, einsum means that you iterate for all possible values of i, j, k, l (so 4 nested loops, but done efficiently in numpy. Anyway, you need to read all values, so that is a minimum in terms of number of operations). And along the repeated index (here, j), result is the sum of product of values from both array. So here, with ijkl,j
, it means
res=np.empty((3,32,32))
for i in range(3):
for k in range(32):
for l in range(32):
res[i,k,l] = 0
for j in range(32):
res[i,k,l] = bits[i,j,k,l]*coef[j]
But really, really fast. Generally, you can't beat np.einsum
.
(Note: I am not sure which bit is the most significant from your point of view. You may need to revert coef. For example, by passing coef[::-1]
to einsum
)