【问题标题】:Loop over all elements of an ndarray one by one一个一个地循环遍历ndarray的所有元素
【发布时间】:2018-05-23 18:24:02
【问题描述】:
In [6]: a = np.array([[1,2,3,4],[5,6,7,8]])

In [7]: b = a

In [8]: a[0]
Out[8]: array([1, 2, 3, 4])

In [9]: a[0][0]
Out[9]: 1

但我想使用zip 并循环遍历ab 并得到a[0][0],然后是a[0][1],直到我到达a[1][3]

当我尝试以下操作时:

In [11]: for i,j in zip(a,b):
    ...:     print i[0][0]
    ...:     
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-11-8a9c71fab781> in <module>()
      1 for i,j in zip(a,b):
----> 2     print i[0][0]
      3 

IndexError: invalid index to scalar variable.

我想获得a[0][0] = 1,然后是a[0][1] = 2,直到a[0][3] = 4,然后获得a[1][0] = 5,依此类推,直到a[1][3] = 8

【问题讨论】:

  • 对不起,我不确定我是否理解。您希望循环的前几个输出是什么?
  • 您希望输出是什么?您是否需要遍历a两个 副本?
  • @ivan_pozdeev:我想得到a[0][0] = 1,然后是a[0][1] = 2,直到a[0][3] = 4,然后得到a[1][0] = 5,依此类推,直到a[1][3] = 8
  • 如果您在 a 上运行 for 循环,那么您将遍历该元素。使用 i[0] 打印您想要的内容。
  • 这就是你已经拥有的?

标签: python numpy for-loop


【解决方案1】:

获取压缩和索引的一种方法是使用np.nditer

>>> a = np.arange(1,9).reshape(2,4)
>>> b = -a
>>> 
>>> it = np.nditer((a, b), order='C', flags=('multi_index',))
>>> for i, j in it:
...     print(it.multi_index, i, j)
... 
(0, 0) 1 -1
(0, 1) 2 -2
(0, 2) 3 -3
(0, 3) 4 -4
(1, 0) 5 -5
(1, 1) 6 -6
(1, 2) 7 -7
(1, 3) 8 -8

作为免费奖励,它会在适当的时候进行广播:

>>> a, b = np.ogrid[1:3, 2:6]
>>> a.shape, b.shape
((2, 1), (1, 4))
>>> 
>>> it = np.nditer((a, b), order='C', flags=('multi_index',))
>>> for i, j in it:
...     print(it.multi_index, i, j)
... 
(0, 0) 1 2
(0, 1) 1 3
(0, 2) 1 4
(0, 3) 1 5
(1, 0) 2 2
(1, 1) 2 3
(1, 2) 2 4
(1, 3) 2 5

【讨论】:

  • np.ndindex 像这样使用multi_index 来生成所有元素的索引。
【解决方案2】:

如果你只是需要一个一个循环遍历a的所有元素,这就是ndarray.flat的用途:

In [11]: a = np.array([[1,2,3,4],[5,6,7,8]])

In [13]: for i in a.flat: print(i)
1
2
3
4
5
6
7
8

循环a.flatten() 会产生相同的结果,但会构造一个单独的ndarray 并复制数据。

.flat 也比itertools.chain.from_iterable(a) 更高效,因为后者涉及从a 获取完整行作为视图,然后对其进行迭代——即许多额外的操作。


如果您在迭代时需要知道索引,请使用numpy.ndenumerate 代替Iterating over a numpy array

In [34]: for (x,y),i in np.ndenumerate(a): print("a[%d][%d]=%d"%(x,y,i))
a[0][0]=1
a[0][1]=2
a[0][2]=3
a[0][3]=4
a[1][0]=5
a[1][1]=6
a[1][2]=7
a[1][3]=8

【讨论】:

  • 你有 chain.from_itable 创建 list 对象的参考吗?我认为重点在于它很懒,而且创建列表。
  • @jpp chain源材料 是完整的行:for r in a: print(r) =&gt; [1 2 3 4]\n[5 6 7 8]。它们不是lists,而是ndarrays 指向a 的数据,因此开销低于我的预期,但仍高于.flat
【解决方案3】:
In [333]: a = np.array([[1,2,3,4],[5,6,7,8]])
In [334]: a
Out[334]: 
array([[1, 2, 3, 4],
       [5, 6, 7, 8]])

获取值及其索引的便捷方法是ndenumerate

In [335]: np.ndenumerate(a)
Out[335]: <numpy.lib.index_tricks.ndenumerate at 0x7f39160b5160>
In [336]: list(_)
Out[336]: 
[((0, 0), 1),
 ((0, 1), 2),
 ((0, 2), 3),
 ((0, 3), 4),
 ((1, 0), 5),
 ((1, 1), 6),
 ((1, 2), 7),
 ((1, 3), 8)]

它创建一个iter = a.flat 一个flatiter 对象,然后对其进行迭代,返回coordsnext

如果你只想要值,而不是坐标

In [19]: list(a.flat)
Out[19]: [1, 2, 3, 4, 5, 6, 7, 8]

ndindex 可用于为给定形状生成索引:

In [20]: idx=np.ndindex(a.shape)
In [21]: [(ij, a[ij]) for ij in idx]
Out[21]: 
[((0, 0), 1),
 ((0, 1), 2),
 ((0, 2), 3),
 ((0, 3), 4),
 ((1, 0), 5),
 ((1, 1), 6),
 ((1, 2), 7),
 ((1, 3), 8)]

【讨论】:

    【解决方案4】:

    从您想要的输出1, 2, ..., 4, 5, ..., 8,您可以使用itertools.chain 来迭代值:

    import numpy as np
    from itertools import chain
    
    a = np.array([[1,2,3,4],[5,6,7,8]])
    
    for i in chain.from_iterable(a):
        print(i)
    
    1
    2
    3
    4
    5
    6
    7
    8
    

    【讨论】:

      【解决方案5】:

      我会试试这个

      a = np.array([[1,2,3,4],[5,6,7,8]])
      for row in [0,1]:
          for column in range(4):
              print('a[%s][%s] = %s' % (row, column, a[row][column]))
      

      打印:

      a[0][0] = 1
      a[0][1] = 2
      a[0][2] = 3
      a[0][3] = 4
      a[1][0] = 5
      a[1][1] = 6
      a[1][2] = 7
      a[1][3] = 8
      

      【讨论】:

        猜你喜欢
        • 2020-08-18
        • 1970-01-01
        • 2020-12-22
        • 2018-05-17
        • 2017-04-29
        • 1970-01-01
        • 2012-10-29
        • 1970-01-01
        • 2021-10-26
        相关资源
        最近更新 更多