【问题标题】:Iterate over numpy with index (numpy equivalent of python enumerate)用索引迭代numpy(numpy相当于python枚举)
【发布时间】:2017-06-24 06:28:24
【问题描述】:

我正在尝试创建一个函数来计算多维 numpy 数组中元素之间的格子距离(水平和垂直步数)。为此,我需要在遍历数组时从每个元素的索引中检索实际数字。我想将这些值存储为可以通过距离公式计算的数字。

对于示例数组 A

 A=np.array([[1,2,3],[4,5,6],[7,8,9]])

我想创建一个循环遍历每个元素,对于第一个元素 1,它将检索 a=0, b=0,因为 1 在 A[0,0],然后 a=0, b= 1 代表元素 2,因为它位于 A[0,1],依此类推...

我设想的输出是数组中每个元素的两个数字(对应于该元素的两个索引值)。所以在上面的例子中,我分配的两个值是 a 和 b。我只需要在循环中检索这两个数字(而不是单独保存为另一个数据对象)。

任何关于如何做到这一点的想法将不胜感激!

【问题讨论】:

  • 由于您对问题的描述有些难以理解,您能否为您的示例提供一个示例预期输出?到目前为止听起来你想要一个所有索引对的列表/数组。
  • 感谢您提出的澄清建议!如果还不清楚,请告诉我。
  • 列表/数组很好,但更简单的是,我只需要在每次迭代中检索两个索引值,因为我会在检索它们后立即将它们输入另一个公式。

标签: python numpy


【解决方案1】:

随着我越来越熟悉 numpy 和 pandas 生态系统,我越来越清楚迭代通常是完全错误,因为它比较慢,并且使用矢量化最好尽可能操作。虽然一开始风格并不那么明显/Pythonic,但我(有趣地)通过矢量化操作获得了可笑的加速;在换出诸如某些行迭代之类的表单的情况下超过 1000 倍 .apply(lambda)

@MSeifert's answer 更好地提供了这一点,并且在任何实际大小的数据集上都将显着提高性能


原答案

您可以使用 numpy.ndenumerate 遍历数组中的值,以获取数组中值的索引。

使用上面的文档:

A = np.array([[1,2,3],[4,5,6],[7,8,9]])
for index, values in np.ndenumerate(A):
    print(index, values)  # operate here

【讨论】:

    【解决方案2】:

    您可以使用np.ndenumerate 来完成此操作,但通常您不需要遍历数组。

    您可以简单地创建一个网格网格(或开放网格)来一次获取所有索引,然后您可以更快地处理它们(矢量化)。

    例如

    >>> x, y = np.mgrid[slice(A.shape[0]), slice(A.shape[1])]
    >>> x
    array([[0, 0, 0],
           [1, 1, 1],
           [2, 2, 2]])
    >>> y
    array([[0, 1, 2],
           [0, 1, 2],
           [0, 1, 2]])
    

    这些可以像任何其他数组一样处理。因此,如果需要索引的函数可以矢量化,则不应执行手动循环!

    例如计算每个点到点的点阵距离,比如(2, 3)

    >>> abs(x - 2) + abs(y - 3)
    array([[5, 4, 3],
           [4, 3, 2],
           [3, 2, 1]])
    

    对于距离,ogrid 会更快。只需将np.mgrid 替换为np.ogrid

    >>> x, y = np.ogrid[slice(A.shape[0]), slice(A.shape[1])]
    >>> np.hypot(x - 2, y - 3)  # cartesian distance this time! :-)
    array([[ 3.60555128,  2.82842712,  2.23606798],
           [ 3.16227766,  2.23606798,  1.41421356],
           [ 3.        ,  2.        ,  1.        ]])
    

    【讨论】:

      【解决方案3】:

      另一种可能的解决方案:

      import numpy as np
      
      A=np.array([[1,2,3],[4,5,6],[7,8,9]])
      for _, val in np.ndenumerate(A):
          ind = np.argwhere(A==val)
          print val, ind
      

      在这种情况下,如果值不是在数组中出现一次,您将获得索引数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-06
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 1970-01-01
        • 2016-02-21
        • 2016-03-09
        • 1970-01-01
        相关资源
        最近更新 更多