可以说我有一个(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数组中的相同索引中提取值并将其放入列表中。
答案 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]
这个技巧有效得多吗?