首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Numpy.argpartition按排序顺序获取每列的k-最小值。

使用Numpy.argpartition按排序顺序获取每列的k-最小值。
EN

Stack Overflow用户
提问于 2017-03-18 13:24:54
回答 3查看 951关注 0票数 0

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

代码语言:javascript
运行
复制
>>> 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-最小值,而不增加时间复杂度。有什么建议吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-18 14:33:56

要使用np.argpartition并保持排序顺序,我们需要使用这些元素的范围作为range(k),而不是只输入标量kth参数-

代码语言:javascript
运行
复制
idx = np.argpartition(myBigArray, range(num), axis=1)[:, :num]
out = myBigArray[np.arange(idx.shape[0])[:,None], idx]
票数 3
EN

Stack Overflow用户

发布于 2017-03-18 14:43:08

您可以使用与行相同的技巧;与@Divakar的排序技巧相结合,这将成为

代码语言:javascript
运行
复制
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]])
票数 1
EN

Stack Overflow用户

发布于 2017-03-18 13:47:11

一点间接索引就行了。请注意,自从您开始处理行以来,我一直在处理行。

代码语言:javascript
运行
复制
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 )慢几倍。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42874944

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档