使用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最小值,而不会增加时间复杂度。 有什么建议??
答案 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