使用Numpy.argpartition以排序顺序获取每列的k最小值

时间:2017-03-18 13:24:54

标签: python-2.7 numpy

使用np.argpartition,它不会对整个数组进行排序。它只保证第k个元素处于排序位置,所有较小的元素将在它之前移动。因此,前k个元素将是k个最小元素

>>> num = 3
>>> myBigArray=np.array([[1,3,2,5,7,0],[14,15,6,5,7,0],[17,8,9,5,7,0]])
>>> top = np.argpartition(myBigArray, num, axis=1)[:, :num]
>>> print top
[[5 0 2]
[3 5 2]
[5 3 4]]
>>> myBigArray[np.arange(myBigArray.shape[0])[:, None], top]
[[0 1 2]
[5 0 6]
[0 5 7]]

返回每列的k最小值。请注意,这些可能不是按排序顺序。我使用此方法,因为以这种方式按排序顺序获取top-k元素需要O(n + k log k)时间 我希望按排序顺序获取每列的k最小值,而不会增加时间复杂度。 有什么建议??

3 个答案:

答案 0 :(得分:3)

要使用np.argpartition并维护排序顺序,我们需要将这些元素范围用作range(k),而不是只使用标量kth参数 -

idx = np.argpartition(myBigArray, range(num), axis=1)[:, :num]
out = myBigArray[np.arange(idx.shape[0])[:,None], idx]

答案 1 :(得分:1)

您可以使用在行的情况下使用的完全相同的技巧;结合@Divakar的排序技巧,这就变成了

In [42]: num = 2

In [43]: myBigArray[np.argpartition(myBigArray, range(num), axis=0)[:num, :], np.arange(myBigArray.shape[1])[None, :]]
Out[43]: 
array([[ 1,  3,  2,  5,  7,  0],
       [14,  8,  6,  5,  7,  0]])

答案 2 :(得分:0)

一些间接索引可以解决问题。 Pleaese注意到,自从你从行开始以来我一直在处理行。

[HEX]

关于decode fdim = np.arange(3)[:, None] so = np.argsort(myBigArray[fdim, top], axis=-1) tops = top[fdim, so] myBigArray[fdim, tops] # array([[0, 1, 2], [0, 5, 6], [0, 5, 7]]) 参数的注释:我强烈怀疑它不是O(n + k log k);在任何情况下,它通常比手动argpartition + range慢几倍here