【问题标题】:Sortrows with multiple sorting keys in numpy在numpy中具有多个排序键的排序
【发布时间】:2013-09-26 00:47:39
【问题描述】:

我还没有在 SO 上找到这个答案,所以我在这里分享它:

问题:当有多个排序键时,如何在 matlab 中模拟 sortrows 功能?在 matlab 中,这看起来像例如:

sortrows(x,[3,-4])

首先按第 3 列排序,然后按第 2 列排序。

如果您按一列排序,您可以使用np.argsort 来查找该列的索引,并应用这些索引。但是如何为多个列做到这一点?

【问题讨论】:

    标签: python arrays sorting numpy


    【解决方案1】:

    语法很笨拙,看起来很奇怪,但最干净的做法是np.lexsort

    data = np.array([[3, 0, 0, .24],
                     [4, 1, 1, .41],
                     [2, 1, 1, .63],
                     [1, 1, 3, .38]]) #imagine rows of a spreadsheet
    #now do sortrows(data,[3,-4])
    ix = np.lexsort((data[:, 3][::-1], data[:, 2])) 
    #this yields [0, 2, 1, 3]
    
    #note that lexsort sorts first from the last row, so sort keys are in reverse order
    
    data[ix]
    

    【讨论】:

      【解决方案2】:

      EDIT2:由于python中的负数是有意义的,我认为它们不应该用于指定列的降序,因此我在这里使用了一个辅助降序对象。

      import numpy as np
      
      class Descending:
          """ for np_sortrows: sort column in descending order """
          def __init__(self, column_index):
              self.column_index = column_index
      
          def __int__(self):  # when cast to integer
              return self.column_index
      
      
      def np_sortrows(M, columns=None):
          """  sorting 2D matrix by rows
          :param M: 2D numpy array to be sorted by rows
          :param columns: None for all columns to be used,
                          iterable of indexes or Descending objects
          :return: returns sorted M
          """
          if len(M.shape) != 2:
              raise ValueError('M must be 2d numpy.array')
          if columns is None:  # no columns specified, use all in reversed order
              M_columns = tuple(M[:, c] for c in range(M.shape[1]-1, -1, -1))
          else:
              M_columns = []
              for c in columns:
                  M_c = M[:, int(c)]
                  if isinstance(c, Descending):
                      M_columns.append(M_c[::-1])
                  else:
                      M_columns.append(M_c)
              M_columns.reverse()
      
          return M[np.lexsort(M_columns), :]
      
      data = np.array([[3, 0, 0, .24],
                       [4, 1, 1, .41],
                       [2, 1, 3, .25],
                       [2, 1, 1, .63],
                       [1, 1, 3, .38]])
      
      # third column is index 2, fourth column in reversed order at index 3    
      print(np_sortrows(data, [2, Descending(3)]))
      

      【讨论】:

      • 现在应该修复
      • 这比它需要的要复杂得多。 my_list_or_array[::-1] 是 Python 中的标准,用于在保持其类型的同时获取列表或数组的反转。你也可以使用reversed,这样更快更容易阅读。它返回一个迭代器。
      • 我实际上在 M_columns.append(M_c[::-1]) 中使用它来进行降序
      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 2016-06-03
      • 2012-10-04
      • 2014-07-08
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多