mat_a = np.random.random((5, 5))
mat_b = np.random.random((5, 5))
mat_c = np.random.random((5, 5))
bigmat = np.stack((mat_a, mat_b, mat_c)) # this is a 3, 5, 5 array
for (x, y, z), value in np.ndenumerate(bigmat):
print (x, y, z)
在上面的例子中,我如何循环使得我只遍历5 x 5数组并且在每个位置我得到3个值,即循环应该运行25次,每次,我得到一个具有3个值的数组(一个来自mat_a,mat_b和mat_c)
bigmat
被重新整形,应该有一种基于特定y,z 答案 0 :(得分:3)
有一个函数可以生成给定形状的所有索引ndindex
。
for y,z in np.ndindex(bigmat.shape[1:]):
print(y,z,bigmat[:,y,z])
0 0 [ 0 25 50]
0 1 [ 1 26 51]
0 2 [ 2 27 52]
0 3 [ 3 28 53]
0 4 [ 4 29 54]
1 0 [ 5 30 55]
1 1 [ 6 31 56]
...
对于像这样的简单情况,它并不比双for range
循环容易得多。也不会更快;但是你要求迭代。
另一个迭代器是itertools.product(range(5),range(5))
时间方面,产品非常好:
In [181]: timeit [bigmat[:,y,z] for y,z in itertools.product(range(5),range(5
...: ))]
10000 loops, best of 3: 26.5 µs per loop
In [191]: timeit [bigmat[:,y,z] for (y,z),v in np.ndenumerate(bigmat[0,...])]
...:
10000 loops, best of 3: 61.9 µs per loop
转置和重塑是获取三元组列表(或数组)的最快方法 - 但它也没有给出索引:
In [198]: timeit list(bigmat.transpose(1,2,0).reshape(-1,3))
100000 loops, best of 3: 15.1 µs per loop
但是相同的操作从np.mgrid
(或np.meshgrid
)得到索引:
np.mgrid[0:5,0:5].transpose(1,2,0).reshape(-1,2)
(虽然这个速度非常慢)
答案 1 :(得分:2)
In [33]: bigmat
Out[33]:
array([[[ 0.51701737, 0.90723012, 0.42534365, 0.3087416 , 0.44315561],
[ 0.3902181 , 0.59261932, 0.21231607, 0.61440961, 0.24910501],
[ 0.63911556, 0.16333704, 0.62123781, 0.6298554 , 0.29012245],
[ 0.95260313, 0.86813746, 0.26722519, 0.14738102, 0.60523372],
[ 0.33189713, 0.6494197 , 0.30269686, 0.47312059, 0.84690451]],
[[ 0.95974972, 0.09659425, 0.06765838, 0.36025411, 0.91492751],
[ 0.92421874, 0.31670119, 0.99623178, 0.30394588, 0.30970197],
[ 0.53590091, 0.04273708, 0.97876218, 0.09686119, 0.78394054],
[ 0.5463358 , 0.29239676, 0.6284822 , 0.96649507, 0.05261606],
[ 0.91733464, 0.77312656, 0.45962704, 0.06446105, 0.58643379]],
[[ 0.75161903, 0.43286354, 0.09633492, 0.52275049, 0.40827006],
[ 0.51816158, 0.05330978, 0.49134325, 0.73652136, 0.14437844],
[ 0.83833791, 0.2072704 , 0.18345275, 0.57282927, 0.7218022 ],
[ 0.56180415, 0.85591746, 0.35482315, 0.94562085, 0.92706479],
[ 0.2994697 , 0.99724253, 0.66386017, 0.0121033 , 0.43448805]]])
重塑事物......
new_bigmat = bigmat.T.reshape([25,3])
In [36]: new_bigmat
Out[36]:
array([[ 0.51701737, 0.95974972, 0.75161903],
[ 0.3902181 , 0.92421874, 0.51816158],
[ 0.63911556, 0.53590091, 0.83833791],
[ 0.95260313, 0.5463358 , 0.56180415],
[ 0.33189713, 0.91733464, 0.2994697 ],
[ 0.90723012, 0.09659425, 0.43286354],
[ 0.59261932, 0.31670119, 0.05330978],
[ 0.16333704, 0.04273708, 0.2072704 ],
[ 0.86813746, 0.29239676, 0.85591746],
[ 0.6494197 , 0.77312656, 0.99724253],
[ 0.42534365, 0.06765838, 0.09633492],
[ 0.21231607, 0.99623178, 0.49134325],
[ 0.62123781, 0.97876218, 0.18345275],
[ 0.26722519, 0.6284822 , 0.35482315],
[ 0.30269686, 0.45962704, 0.66386017],
[ 0.3087416 , 0.36025411, 0.52275049],
[ 0.61440961, 0.30394588, 0.73652136],
[ 0.6298554 , 0.09686119, 0.57282927],
[ 0.14738102, 0.96649507, 0.94562085],
[ 0.47312059, 0.06446105, 0.0121033 ],
[ 0.44315561, 0.91492751, 0.40827006],
[ 0.24910501, 0.30970197, 0.14437844],
[ 0.29012245, 0.78394054, 0.7218022 ],
[ 0.60523372, 0.05261606, 0.92706479],
[ 0.84690451, 0.58643379, 0.43448805]])
编辑:要跟踪索引,您可以尝试以下操作(在此处打开其他想法)。 xy_index
中的每一行分别为new_bigmat
数组中的相应行提供x,y值。这个答案并不需要任何循环。如果循环可以接受,您可以在评论中借用Simon的建议,或者按照hpaulj的回答中的建议np.ndindex
。
row_index, col_index = np.meshgrid(range(5),range(5))
xy_index = np.array([row_index.flatten(), col_index.flatten()]).T
In [48]: xy_index
Out[48]:
array([[0, 0],
[1, 0],
[2, 0],
[3, 0],
[4, 0],
[0, 1],
[1, 1],
[2, 1],
[3, 1],
[4, 1],
[0, 2],
[1, 2],
[2, 2],
[3, 2],
[4, 2],
[0, 3],
[1, 3],
[2, 3],
[3, 3],
[4, 3],
[0, 4],
[1, 4],
[2, 4],
[3, 4],
[4, 4]])
答案 2 :(得分:1)
可以通过切片获得所需的结果,例如:
for x in range(5):
for y in range(5):
print (bigmat[:,x,y])
答案 3 :(得分:0)
如果您实际上不需要堆叠数组,并且只想迭代所有三个数组,那么元素,一次,numpy.nditer可以工作 - 我&# 39; m仍然模糊了所有参数我不知道它是否更快,在子集上进行测试。
a1 = np.arange(9).reshape(3,3) + 10
a2 = np.arange(9).reshape(3,3) + 20
a3 = np.arange(9).reshape(3,3) + 30
c = np.nditer((a1, a2, a3))
for thing in c:
print(np.array(thing))
>>>
[10 20 30]
[11 21 31]
[12 22 32]
[13 23 33]
[14 24 34]
[15 25 35]
[16 26 36]
[17 27 37]
[18 28 38]
>>>