【问题标题】:Most efficient way of iterating over a numpy array by axis?按轴迭代numpy数组的最有效方法?
【发布时间】:2015-06-12 03:27:21
【问题描述】:

我有一个 3 维的 numpy 数组。 我想迭代 2 个昏暗并在第 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

【问题讨论】:

    标签: python arrays loops numpy


    【解决方案1】:

    您可以为此使用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]])
    

    【讨论】:

      【解决方案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)
      

      这是我的速度赢家。

      【讨论】:

      • 嗨@hpaulj,你能看看这个Q stackoverflow.com/questions/38207528/…我有一个可行的方法从这个A,但我怀疑它是最佳的。
      • 对于ndindex,是否可以说给我索引,这会给我所有行的所有列的所有第二层?例如(3, 3, 3) 的形状,我只想遍历(0,0,1), (0,1,1), (0,2,1) ...
      • 我不会为此使用ndindex,只需进行一维迭代:for i in range(3): idx=(0, i, 1)
      猜你喜欢
      • 2021-03-07
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      • 2011-10-09
      • 1970-01-01
      • 2021-02-18
      相关资源
      最近更新 更多