从4D数组中的相同索引获取值列表

时间:2018-08-08 15:52:00

标签: python arrays numpy

可以说我有一个(3, 3, 3)形状的3D数组(一个立方体)。其中有5个,因此总共有一个(5, 3, 3, 3)形状的4D数组。

我现在希望进入5个3D数组中的第一个,并获取索引(1, 1, 1)的值。需要对所有3D数组重复进行此操作,以便最终得到5个值的列表/向量,每个值均来自所有5个3D数组中的索引(1, 1, 1)

理论上,我可能会做类似的事情:

import numpy as np

xn = 2
yn = 2
zn = 5
pats = 10

array = np.random.rand(pats, xn, yn, zn)

new_array = []
for x in range(0, xn, 1):
    for y in range(0, yn, 1):
        for z in range(0, zn, 1):
            for pat in range(0, pats, 1):
                array_temp = array[pat, x, y, z]
                new_array.append(array_temp)

尽管,在这种情况下,我只是获得了所有10个(2, 2, 5)数组中的所有值的一维列表(在此示例中),而不是20个列表(2 * 2 * 5),每个列表中都有10个值。

总而言之,在3D数组可能为(100, 100, 100)pat = 1000的情况下,我不确定(如果代码已纠正)在计算时间方面是否最佳。因此,我想知道Numpy是否具有某种工具,可以从每个3D数组中的相同索引中提取值并将其放入列表中。

2 个答案:

答案 0 :(得分:1)

通过迭代代码x->y->z->pat并将其追溯到设置为pat->xn->yn->zn的输入数组,我们只需要置换轴,将第一个轴向后推,从而将其删除所有这些嵌套循环,就像这样-

new_array = array.transpose(1,2,3,0)

如果我们希望最终输出是平坦的,请使用.ravel()-

new_array = array.transpose(1,2,3,0).ravel()

使用np.moveaxis可能会更直观,更通用-

new_array = np.moveaxis(array,0,-1).ravel()

或与np.rollaxis-

new_array = np.rollaxis(array,0,4).ravel()

样品运行-

In [45]: xn = 2
    ...: yn = 2
    ...: zn = 5
    ...: pats = 10
    ...: 
    ...: np.random.seed(0)
    ...: array = np.random.rand(pats, xn, yn, zn)
    ...: 
    ...: new_array = []
    ...: for x in range(0, xn, 1):
    ...:     for y in range(0, yn, 1):
    ...:         for z in range(0, zn, 1):
    ...:             for pat in range(0, pats, 1):
    ...:                 array_temp = array[pat, x, y, z]
    ...:                 new_array.append(array_temp)

In [46]: np.allclose(new_array, array.transpose(1,2,3,0).ravel())
Out[46]: True

内存效率和性能

未展平的版本只是输入数组的视图,因此不会有额外的内存开销,并且实际上是免费的,如下所示-

In [55]: xn = 20
    ...: yn = 20
    ...: zn = 50
    ...: pats = 100
    ...: 
    ...: np.random.seed(0)
    ...: array = np.random.rand(pats, xn, yn, zn)

In [56]: %timeit array.transpose(1,2,3,0)
1000000 loops, best of 3: 270 ns per loop

In [57]: np.shares_memory(array, array.transpose(1,2,3,0))
Out[57]: True

答案 1 :(得分:0)

不会

my_arr = array[:,1,1,1]

这个技巧有效得多吗?