繁体   English   中英

如何通过合并元素将 4 维数组的形状缩小为 3 维数组?

[英]How do I reduce the shape of my 4-d array to 3-d by merging the elements?

我有一个 4 维数组,形状为(3,32,32,32)为 1 位,我想将其减少为(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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM