识别numpy中值的偏移量
给定一个扁平化的 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
已经返回了一个数组。