【问题标题】:In numpy, why does flatiter access past the end of the ndarray?在 numpy 中,为什么 flatiter 访问超过 ndarray 的末尾?
【发布时间】:2023-03-26 02:01:01
【问题描述】:

我想使用 numpy.ndarray 迭代器的 flatiter.coords 属性,但我遇到了奇怪的行为。考虑一个简单的程序

xflat = np.zeros( (2, 3) ).flat

while True:
    try:
        print( xflat.coords )
        xflat.next()
    except StopIteration:
        break

此代码产生以下输出:

(0, 0)
(0, 1)
(0, 2)
(1, 0)
(1, 1)
(1, 2)
(2, 0)

最后一个坐标无效 - 没有 (2,0) 坐标。这意味着我不能在没有进一步检查的情况下使用 flatiter.coords 属性,因为它会抛出一个无效的索引。

为什么会这样?是故意的吗?

【问题讨论】:

    标签: numpy multidimensional-array iterator


    【解决方案1】:

    我不知道它是否真的是故意的,但引用的元素和坐标似乎是一次性的:

    Help on getset descriptor numpy.flatiter.coords:
    
    coords
    An N-dimensional tuple of current coordinates.
    
    Examples
    --------
    >>> x = np.arange(6).reshape(2, 3)
    >>> fl = x.flat
    >>> fl.coords
    (0, 0)
    >>> fl.next()
    0
    >>> fl.coords
    (0, 1)
    

    我倾向于同意你的观点,它看起来像一个错误。

    【讨论】:

      【解决方案2】:

      虽然我有时使用x.flat 以散列形式引用数组,但我从未使用或见过coords 的使用。

      In [136]: x=np.arange(6).reshape(2,3)    
      In [137]: xflat = x.flat
      In [138]: for v in xflat:
           ...:     print(v, xflat.index, xflat.coords)
           ...:     
      0 1 (0, 1)
      1 2 (0, 2)
      2 3 (1, 0)
      3 4 (1, 1)
      4 5 (1, 2)
      5 6 (2, 0)
      

      似乎indexcoords 引用了下一个值,而不是当前值。对于第一行,当前索引为 0,坐标为 (0,0)。所以最后一个确实是'off-the-end',这就是迭代退出的原因。

      In [155]: xflat=x.flat
      In [156]: xflat.coords, xflat.index
      Out[156]: ((0, 0), 0)
      

      这是我如何使用flat

      In [143]: y=np.zeros((3,2))
      In [144]: y.flat[:] = x.flat
      In [145]: y
      Out[145]: 
      array([[ 0.,  1.],
             [ 2.,  3.],
             [ 4.,  5.]])
      

      我不会将它用于索引迭代。

      这样更好:

      In [147]: for i,v in np.ndenumerate(x):
           ...:     print(i,v)
           ...:     
      (0, 0) 0
      (0, 1) 1
      (0, 2) 2
      (1, 0) 3
      (1, 1) 4
      (1, 2) 5
      

      或者对于一维迭代:

      for i,v in enumerate(x.flat):
          print(i,v)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-17
        • 1970-01-01
        • 2013-11-20
        • 2016-10-26
        • 1970-01-01
        • 2020-08-16
        • 2021-10-17
        • 2020-03-26
        相关资源
        最近更新 更多