识别numpy中值的偏移量

0 投票
2 回答
809 浏览
提问于 2025-04-18 01:35

给定一个扁平化的 NxN 数组(也就是一个二维数组),我想找到最小值以及它在数组中的位置。我已经找到了最小值,但能不能确定它的位置(是在哪一行和哪一列)呢?

在下面的例子中,a = 0.5,我怎么知道这个 0.5 是来自 [1,0] 这个位置,还是 [2,1] 这个位置呢?

from numpy import *

value = 0
NUM_NODE = 5
EDGE = array(zeros((NUM_NODE, NUM_NODE)))
EDGE = [[ 0.,          0.,          0.,          0.,          0.        ],
    [ 0.5,         0.,          0.,          0.,          0.        ],
    [ 1.,          0.5,         0.,          0.,          0.        ],
    [ 1.41421356,  1.11803399,  1.,          0.,          0.        ],
    [ 1.,          1.11803399,  1.41421356,  1.,          0.        ]]

a = reshape(EDGE, NUM_NODE*NUM_NODE)
print min(filter(lambda x : x > value, a))

2 个回答

2

numpy.ndenumerate 是一个可以遍历数组的工具(顺便说一下,重塑数组的时候你不应该丢失位置信息)。

In [43]: a = array(EDGE)

In [44]: a
Out[44]: 
array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.5       ,  0.        ,  0.        ,  0.        ,  0.        ],
       [ 1.        ,  0.5       ,  0.        ,  0.        ,  0.        ],
       [ 1.41421356,  1.11803399,  1.        ,  0.        ,  0.        ],
       [ 1.        ,  1.11803399,  1.41421356,  1.        ,  0.        ]])

In [45]: min((i for i in ndenumerate(a) if i[1] > 0), key=lambda i: i[1])
Out[45]: ((1, 0), 0.5)

如果你想要每个出现的地方,也可以用老办法来实现:

In [11]: m, ms = float("inf"), []

In [12]: for pos, i in ndenumerate(a):
   ....:     if not i: continue
   ....:     if i < m: 
   ....:         m, ms = i, [pos]
   ....:     elif i == m:
   ....:         ms.append(pos)
   ....:         

In [13]: ms
Out[13]: [(1, 0), (2, 1)]
3

你可以使用 np.where

>>> edge = np.array(EDGE) 
>>> edge[edge > 0].min()
0.5
>>> np.where(edge == edge[edge > 0].min())
(array([1, 2]), array([0, 1]))

这个方法会分别给出达到最小值的 x 坐标和 y 坐标。如果你想把它们结合起来,有很多方法可以做到,比如:

>>> np.array(np.where(edge == edge[edge > 0].min())).T
array([[1, 0],
       [2, 1]])

顺便说一下,使用 from numpy import * 是个坏习惯,因为这样会把一些内置函数替换成 numpy 的版本,而这些版本的工作方式不同,有时结果甚至是相反的;而且,变量名用全大写通常是给常量用的;另外,你的

 EDGE = array(zeros((NUM_NODE, NUM_NODE)))

这一行没有任何作用,因为你的 EDGE = [[ 0., ... etc 这一行立刻创建了一个新的 list 并把 EDGE 绑定到它上面。你创建了一个数组却把它扔掉了。而且这里其实不需要调用 array;因为 zeros 已经返回了一个数组。

撰写回答