通过轴迭代numpy数组的最有效方法?

时间:2015-04-07 13:48:19

标签: python arrays loops numpy

我有一个3维的numpy数组。 我想迭代2个dims并在第3个昏暗中拉出所有东西。 即:

arr = numpy.random.rand(3,5,5)

for i in range(arr.shape[1]):
    for j in range(arr.shape[2]):
        print arr[:, i, j]

这是最有效的循环方式吗?我知道numpy为循环提供了更有效的nditer函数,但它似乎不能像这样做

我将使用的实际数组大小约为30x256x256

2 个答案:

答案 0 :(得分:2)

您可以使用numpy.transpose

>>> x, y, z = arr.shape
>>> np.transpose(arr, (1, 2, 0)).reshape(y*z, x)
array([[  8.89189379e-01,   5.95637587e-01,   7.84594074e-01],
       [  4.46214496e-01,   6.95533725e-03,   5.99493854e-02],
       [  4.37458356e-01,   4.17801277e-01,   8.70384164e-01],
       [  1.22083367e-01,   3.15002894e-01,   9.61295653e-01],
       [  2.15219210e-01,   5.99682222e-01,   8.59042071e-01],
       [  7.39714387e-01,   6.06449305e-01,   1.53375491e-01],
       [  4.34580313e-01,   8.23793966e-01,   2.58262432e-01],
       [  6.53256475e-01,   9.10842288e-01,   6.62668876e-01],
       [  2.60638435e-01,   2.44083731e-01,   9.44411275e-01],
       [  3.46072029e-01,   3.36690811e-01,   5.56281161e-04],
       [  5.54365956e-01,   7.84576199e-01,   2.92020128e-01],
       [  6.98475648e-01,   7.59483427e-01,   8.09173748e-01],
       [  7.28369542e-01,   2.07783197e-01,   3.36918305e-01],
       [  3.64955373e-01,   2.09863710e-01,   4.68231831e-02],
       [  9.10347730e-01,   2.59136721e-01,   7.71923984e-01],
       [  6.86310347e-01,   5.99903493e-01,   1.93947009e-01],
       [  1.28353564e-01,   4.04525015e-01,   8.46140174e-01],
       [  4.54025659e-01,   8.81360670e-01,   4.43411994e-01],
       [  6.57856096e-01,   3.55154332e-02,   6.74960684e-01],
       [  8.58154335e-01,   2.44856092e-01,   7.33027949e-01],
       [  2.09503288e-01,   1.20565562e-01,   5.44488104e-01],
       [  4.67728847e-02,   6.54273408e-02,   4.70930711e-02],
       [  3.70647262e-02,   5.72090215e-01,   4.38541549e-01],
       [  7.30252318e-01,   4.96902990e-02,   5.80768124e-01],
       [  4.92665142e-01,   9.16531057e-01,   8.29183892e-01]])

答案 1 :(得分:2)

根据最近的问题调整我的答案,您可以使用ndindex https://stackoverflow.com/a/29467367/901925

for tup in np.ndindex((arr.shape[1:])):
    tup1=(slice(None),tup[0],tup[1])
    print arr[tup1]

这使用nditer生成multi_index,可以与slice结合生成所需的索引。

nditer教程页面还会显示混合的orderexternal_loop属性如何使nditer返回sub_vector,但这很棘手。

nditer不是更“有效”或更快。您仍然最终索引每个元素,或者在第一个维度上为切片编制索引。 nditer作为编码问题cython的一步,非常有用。在纯Python中,它与for循环一样慢,甚至更慢。

nditer在您需要同时逐步执行多个数组时也很棒,例如c[i] = a[i]+b[i]

如果必须遍历最后2个维度,那么您所做的可能与任何其他方法一样快。其他方法只是隐藏细节。

您可以探索交换轴或重新整形,例如arr.reshape(3,-1)

for x in arr.reshape(3,-1).T:
    print(x)

这是我速度的赢家。