迭代超过3D Numpy阵列并计算每个序列的百分比变化



我在迭代,广播和通常制作循环代码方面有很大的差距。

我有一组大小的序列(2000,10,200(。我想将每个(10,200(序列(10,200(划分,然后将所有10行除以该序列的第一行,以获得相对于单个窗口的百分比变化。

此外,我只想对200总计的前100个元素执行分隔操作。

使用传统循环的伪代码:

#Loop over each of the 2000 sequences
#Loop over each of the 10 rows
#Divide each row (first 100 elements) by the the first row-1 (first 100 elements) and save

这是我的尝试,尽管它不起作用,也可能不是正确的方法。对代码的任何解释都非常感谢。

for sequence in data:
    for row in data[0][row]:
        data[0][row]  = data[0][row][0:99] / data[0][0][0:99] -1

设置
让我们看一个较小的例子:

data = np.arange(72).reshape(3, 4, 6) + 10
data
array([[[10, 11, 12, 13, 14, 15],
        [16, 17, 18, 19, 20, 21],
        [22, 23, 24, 25, 26, 27],
        [28, 29, 30, 31, 32, 33]],
       [[34, 35, 36, 37, 38, 39],
        [40, 41, 42, 43, 44, 45],
        [46, 47, 48, 49, 50, 51],
        [52, 53, 54, 55, 56, 57]],
       [[58, 59, 60, 61, 62, 63],
        [64, 65, 66, 67, 68, 69],
        [70, 71, 72, 73, 74, 75],
        [76, 77, 78, 79, 80, 81]]])

解决方案
首先确定要分割的最后一个维度

half_last_dim = data.shape[-1] // 2

第二,将第二个维度切成一个长度阵列以保持维度并启用广播

data[:, :, :half_last_dim] / data[:, [0], :half_last_dim]
array([[[ 1.        ,  1.        ,  1.        ],
        [ 1.6       ,  1.54545455,  1.5       ],
        [ 2.2       ,  2.09090909,  2.        ],
        [ 2.8       ,  2.63636364,  2.5       ]],
       [[ 1.        ,  1.        ,  1.        ],
        [ 1.17647059,  1.17142857,  1.16666667],
        [ 1.35294118,  1.34285714,  1.33333333],
        [ 1.52941176,  1.51428571,  1.5       ]],
       [[ 1.        ,  1.        ,  1.        ],
        [ 1.10344828,  1.10169492,  1.1       ],
        [ 1.20689655,  1.20338983,  1.2       ],
        [ 1.31034483,  1.30508475,  1.3       ]]])

分配给data
使data类型float

# Only necessary because my example started with integers.
data = data.astype(float)
data[:, :, :half_last_dim] /= data[:, [0], :half_last_dim]
data.round(2)  # rounded for pretty printing
array([[[  1.  ,   1.  ,   1.  ,  13.  ,  14.  ,  15.  ],
        [  1.6 ,   1.55,   1.5 ,  19.  ,  20.  ,  21.  ],
        [  2.2 ,   2.09,   2.  ,  25.  ,  26.  ,  27.  ],
        [  2.8 ,   2.64,   2.5 ,  31.  ,  32.  ,  33.  ]],
       [[  1.  ,   1.  ,   1.  ,  37.  ,  38.  ,  39.  ],
        [  1.18,   1.17,   1.17,  43.  ,  44.  ,  45.  ],
        [  1.35,   1.34,   1.33,  49.  ,  50.  ,  51.  ],
        [  1.53,   1.51,   1.5 ,  55.  ,  56.  ,  57.  ]],
       [[  1.  ,   1.  ,   1.  ,  61.  ,  62.  ,  63.  ],
        [  1.1 ,   1.1 ,   1.1 ,  67.  ,  68.  ,  69.  ],
        [  1.21,   1.2 ,   1.2 ,  73.  ,  74.  ,  75.  ],
        [  1.31,   1.31,   1.3 ,  79.  ,  80.  ,  81.  ]]])

更多说明
请参阅广播规则
为了使广播正确,我们希望我们正在广播的东西与所有维度的尺寸相匹配,除了我们针对的尺寸。为此,我们需要长度1

data.shape
(3, 4, 6)
data[:, [0], :].shape
(3, 1, 6)

最新更新