我有形状为1bit的(3,32,32,32)
的4-d数组,我想将其减少到(3,32,32)
,元素变为32位。数组中的值是0和1。数组中的编号只是一种可视化我的问题的方式,它代表了我想要的32位的结果段的nth
位。
[[[[ 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
很抱歉,如果这是一个如此明显的问题,因为我还在学习。
我希望我的结果数组的大小为(3,32,32)
与以下安排:
[[[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
最快的方法,我认为(也是最短的一个写,虽然不理解,如果你不习惯这个函数)可能是使用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
一行是np.einsum('ijkl,j', bits, [2**k for k in range(32)])
这里使用的einsum意味着迭代i, j, k, l的所有可能值(所以4个嵌套循环,但在numpy中有效地完成)。无论如何,您需要读取所有值,因此这是操作数量方面的最小值)。沿着重复索引(这里是j),结果是两个数组中值的乘积的和。这里,ijkl,j
表示
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]
但是非常非常快。一般来说,你无法打败np.einsum
。
(注意:我不确定从你的角度来看哪位是最重要的。您可能需要还原coef。例如,通过将coef[::-1]
传递给einsum
)