【问题标题】:Python Matrix sorting via one column通过一列进行 Python 矩阵排序
【发布时间】:2012-10-31 13:06:09
【问题描述】:

我有一个 n x 2 整数矩阵。第一列是一个系列 0,1,-1,2,-2,但是这些是按照它们从其组成矩阵中编译的顺序排列的。第二列是另一个列表中的索引列表。

我想通过第二列对矩阵进行排序。这相当于在 Excel 中选择两列数据,然后通过 B 列(其中数据位于 A 列和 B 列中)进行排序。请记住,每行第一列中的相邻数据应与其对应的第二列对应。我使用以下方法查看了解决方案:

data[np.argsort(data[:, 0])]

但这似乎不起作用。有问题的矩阵如下所示:

matrix([[1, 1],
        [1, 3],
        [1, 7],
        ..., 
        [2, 1021],
        [2, 1040],
        [2, 1052]])

【问题讨论】:

    标签: python sorting matrix numpy


    【解决方案1】:

    你的想法是对的,只是差了几个字符:

    >>> import numpy as np
    >>> data = np.matrix([[9, 8],
    ...                   [7, 6],
    ...                   [5, 4],
    ...                   [3, 2],
    ...                   [1, 0]])
    >>> data[np.argsort(data.A[:, 1])]
    matrix([[1, 0],
            [3, 2],
            [5, 4],
            [7, 6],
            [9, 8]])
    

    【讨论】:

    • 感谢@Bi Rico 对此方法的澄清;)
    【解决方案2】:

    你可以使用np.lexsort:

    numpy.lexsort(keys, axis=-1)

    使用键序列执行间接排序。

    给定多个排序键,可以解释为 在电子表格中,lexsort 返回一个整数索引数组 描述多列的排序顺序。


    In [13]: data = np.matrix(np.arange(10)[::-1].reshape(-1,2))
    
    In [14]: data
    Out[14]: 
    matrix([[9, 8],
            [7, 6],
            [5, 4],
            [3, 2],
            [1, 0]])
    
    In [15]: temp = data.view(np.ndarray)
    
    In [16]: np.lexsort((temp[:, 1], ))
    Out[16]: array([4, 3, 2, 1, 0])
    
    In [17]: temp[np.lexsort((temp[:, 1], ))]
    Out[17]: 
    array([[1, 0],
           [3, 2],
           [5, 4],
           [7, 6],
           [9, 8]])
    

    请注意,如果您将多个键传递给np.lexsort,则 last 键是主键。倒数第二个键是第二个键,以此类推。


    使用上面显示的np.lexsort 需要使用临时数组,因为np.lexsort 不适用于numpy 矩阵。自从 temp = data.view(np.ndarray) 创建一个视图,而不是 data 的副本,它不需要太多额外的内存。不过,

    temp[np.lexsort((temp[:, 1], ))]
    

    是一个新数组,确实需要更多内存。

    还有一种按列就地排序的方法。这个想法是将数组视为具有两列的结构化数组。与普通的 ndarray 不同,结构化数组有一个 sort 方法,它允许您将列指定为键:

    In [65]: data.dtype
    Out[65]: dtype('int32')
    
    In [66]: temp2 = data.ravel().view('int32, int32')
    
    In [67]: temp2.sort(order = ['f1', 'f0'])
    

    请注意,由于temp2data视图,它不需要分配新内存和复制数组。另外,排序temp2同时修改data

    In [69]: data
    Out[69]: 
    matrix([[1, 0],
            [3, 2],
            [5, 4],
            [7, 6],
            [9, 8]])
    

    【讨论】:

    • 感谢@unutbu 你的明星!我看第二个解决方案,最好的这个正是我想要的:) 再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2014-06-02
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多