【问题标题】:Geting the k-smallest values of each column in sorted order using Numpy.argpartition使用 Numpy.argpartition 按排序顺序获取每列的 k 最小值
【发布时间】:2017-03-18 13:24:54
【问题描述】:

使用 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 最小值。请注意,这些可能不是按排序顺序排列的。我使用此方法是因为以这种方式按排序顺序获取前 k 个元素需要 O(n + k log k) 时间 我想按排序顺序获取每列的 k 最小值,而不增加时间复杂度。 有什么建议么??

【问题讨论】:

  • 您的问题是如何从最小的k 到最大的(顶部?)k?在您的示例中,您似乎已经处理了最小的情况。或者问题是如何从行到列?
  • 不,我想按排序顺序获取每列的 k 最小值。

标签: python-2.7 numpy


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您可以使用在行的情况下使用的完全相同的技巧;结合@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]])
    

    【讨论】:

      【解决方案3】:

      一点间接索引就可以解决问题。请注意,自从您开始研究行以来,我一直在研究行。

      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]])
      

      关于argpartitionrange 参数的注释: 我强烈怀疑它不是 O(n + k log k);无论如何,它通常比手动慢几倍 argpartition + argsort 请参阅 here

      【讨论】:

      • 任何使用 np.argpartition 的解决方案??
      • @RajaHammadFarooq 它使用argpartition;它在你的第三行之后开始。我的意思是它应该包括前三行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多