使用index迭代numpy(numpy相当于python enumerate)

7bsow1i6  于 2023-06-06  发布在  Python
关注(0)|答案(3)|浏览(654)

我正在尝试创建一个函数,它将计算多维numpy数组中元素之间的晶格距离(水平和垂直步长的数量)。为此,我需要在遍历数组时从每个元素的索引中检索实际数字。我想把这些值存储为数字,这样我就可以用距离公式来计算了。
对于示例数组A

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

我想创建一个循环,遍历每个元素,对于第一个元素1,它将检索a=0,B=0,因为1位于A[0,0],然后对于元素2,a=0,b=1,因为它位于A[0,1],等等......
我设想的输出是数组中每个元素的两个数字(对应于该元素的两个索引值)。因此,在上面的例子中,我将分配给a和b的两个值。我只需要在循环中检索这两个数字(而不是单独保存为另一个数据对象)。
任何关于如何做到这一点的想法将不胜感激!

8iwquhpp

8iwquhpp1#

随着我对numpy和pandas生态系统越来越熟悉,我越来越清楚地认识到,迭代通常是“完全错误的”,因为相比之下它是多么的慢,并且尽可能地使用矢量化操作是最好的。虽然一开始的风格不是那么明显/Pythonic,但我已经(有趣地)获得了 * 荒谬的 * 矢量化操作加速;在交换出表单的情况下,比如一些行迭代.apply(lambda),超过1000 x
@MSeifert's answer更好地提供了这一点,并且在任何真实的大小的数据集上的性能都将显著提高
More general Answer by @cs95 covering and comparing alternatives to iteration in Pandas

原始应答

您可以使用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
2exbekwf

2exbekwf2#

你可以使用np.ndenumerate来实现,但通常你不需要迭代数组。
您可以简单地创建一个meshgrid(或开放网格)来一次获取所有索引,然后可以更快地处理它们(矢量化)。
比如说,

>>> 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.        ]])
xpcnnkqh

xpcnnkqh3#

另一种可能的解决方案:

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)

在这种情况下,如果value在数组中出现不止一次,则将获得索引数组。

相关问题