使用np.argpartition,它不会对整个数组进行排序。它只保证kth元素处于排序位置,所有较小的元素都会在它之前移动。因此,第一个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-最小值,而不增加时间复杂度。有什么建议吗?
发布于 2017-03-18 14:33:56
要使用np.argpartition
并保持排序顺序,我们需要使用这些元素的范围作为range(k)
,而不是只输入标量kth
参数-
idx = np.argpartition(myBigArray, range(num), axis=1)[:, :num]
out = myBigArray[np.arange(idx.shape[0])[:,None], idx]
发布于 2017-03-18 14:43:08
您可以使用与行相同的技巧;与@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]])
发布于 2017-03-18 13:47:11
一点间接索引就行了。请注意,自从您开始处理行以来,我一直在处理行。
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]])
关于argpartition
range
论点的的注记:i强烈怀疑它不是O(n +k log k);无论如何,它通常比手动的argpartition
+ argsort
(见here )慢几倍。
https://stackoverflow.com/questions/42874944
复制相似问题