m来自上三角矩阵的最小值,其索引为元组列表

时间:2017-02-01 01:25:24

标签: python arrays pandas numpy min

我有一个np.ndarray如下:

[(0,1,1),(0,4,1),(3,4,1),(0,3,2)] 

有没有办法获得该nd数组中m个最小项的索引和值?所以,如果我想要4个最小的那个就是

{{1}}

其中(row,col,val)是上面的符号。

如果有多个值,则只需随机选择其中一个值。例如,有3个,然后下一个最小值是2,但(0,3,2),(1,2,2),(1,4,2)都是可能的选择。

基本上,我能否有效地从上三角矩阵中提取该格式的k个最小值(矩阵比上面的例子大得多)。我尝试使用方形,最小的方法展平它,但是我很难将索引和值对齐。谢谢!

3 个答案:

答案 0 :(得分:2)

对于Inf填充的数组 -

r,c = np.unravel_index(a.ravel().argsort()[:4], a.shape)
out = zip(r,c,a[r,c])

为了提高性能,请考虑使用np.argpartition。因此,请将a.ravel().argsort()[:4]替换为np.argpartition(a.ravel(), range(4))[:4]

示例运行 -

In [285]: a
Out[285]: 
array([[ inf,   1.,   3.,   2.,   1.],
       [ inf,  inf,   2.,   3.,   2.],
       [ inf,  inf,  inf,   5.,   4.],
       [ inf,  inf,  inf,  inf,   1.],
       [ inf,  inf,  inf,  inf,  inf]])

In [286]: out
Out[286]: [(0, 1, 1.0), (0, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0)]

对于一般情况 -

R,C = np.triu_indices(a.shape[1],1)
idx = a[R,C].argsort()[:4]
r,c = R[idx], C[idx]
out = zip(r,c,a[r,c])

示例运行 -

In [351]: a
Out[351]: 
array([[ 68.,  67.,  81.,  23.,  16.],
       [ 84.,  83.,  20.,  66.,  48.],
       [ 58.,  72.,  98.,  63.,  30.],
       [ 61.,  40.,   1.,  86.,  22.],
       [ 29.,  95.,  38.,  22.,  95.]])
In [352]: out
Out[352]: [(0, 4, 16.0), (1, 2, 20.0), (3, 4, 22.0), (0, 3, 23.0)]

为了提高性能,请考虑使用np.argpartition。因此,请将a[R,C].argsort()[:4]替换为np.argpartition(a[R,C], range(4))[:4]

答案 1 :(得分:0)

这样的工作:

import numpy as np
a = np.random.rand(4,4)
tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row)]
sorted(tuples,key=lambda x: x[2])[:10]

你问题中k = 10([:10])。

如果您只想要上三角形元素,可以在列表推导中添加条件:

a = np.random.rand(4,4)
tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row) if ix<=iy]
sorted(tuples,key=lambda x: x[2])

答案 2 :(得分:0)

如果我的 np.array() n ,我可以通过展平它(使用* np.ndenumerate())并使用它来获取n个最小值 heapq 模块的 .heapify() .smallest()方法如下:

#!python
flattened = [(y,x) for x,y in np.ndenumerate(n)]
# tuples reversed for natural sorting on values rather than co-ords
heapq.heapify(flattened)
results = heapq.nsmallest(4, flattened)

但是这将使用大量额外的内存,并将Numpy高效数组中的数据和坐标提取到Python的本机列表中。因此,可能有更好的方法在Python中更原生地完成它。