【问题标题】:Sorting numpy matrix for a given column为给定列排序 numpy 矩阵
【发布时间】:2013-06-30 04:39:18
【问题描述】:

我尝试使用 Ned Batchelder 代码按人工顺序对 NumPy 矩阵进行排序,正如以下帖子中所建议的那样:

Sort numpy string array with negative numbers?

代码在一维数组上运行,命令为:

print (sorted(a, key=natural_keys))

现在,我的问题是我的数据是一个 10 列矩阵,我想根据一列对其进行排序(比如说MyColumn)。我找不到修改代码以打印根据这一列排序的整个矩阵的方法。我能想到的就是:

print (sorted(a['MyColumn'], key=natural_keys))

但是,当然,只有MyColumn 出现在输出中,尽管它已正确排序...

有没有办法打印整个矩阵?

这是我用来加载数组的命令(我将原始输入文件简化为 3 列数组):

data = np.loadtxt(inputfile, dtype={'names': ('ID', 'MyColumn', 'length'),
'formats': ('int32', 'S40', 'int32')},skiprows=1, delimiter='\t')

ID  MyColumn    length
164967  BFT_job13_q1_type2  426
197388  BFT_job8_q0_type2   244
164967  BFT_job13_q0_type1  944
72406   BFT_job1_q0_type3   696

理想的输出如下所示:

ID  MyColumn    length
72406   BFT_job1_q0_type3   696
197388  BFT_job8_q0_type2   244
164967  BFT_job13_q0_type1  944
164967  BFT_job13_q1_type2  426

【问题讨论】:

    标签: python numpy sorting matrix


    【解决方案1】:

    如果你有一个np.matrix,叫m

    col = 1
    m[np.array(m[:,col].argsort(axis=0).tolist()).ravel()]
    

    如果你有np.ndarray,叫a

    col = 1
    a[a[:,col].argsort(axis=0)]
    

    如果您有一个带有命名列的结构化数组:

    def mysort(data, col_name, key=None):
        d = data.copy()
        cols = [i[0] for i in eval(str(d.dtype))]
        if key:
            argsort = np.array([key(i) for i in d[col_name]]).argsort()
        else:
            argsort = d[col_name].argsort()
        for col in cols:
            d[col] = d[col][argsort]
        return d
    

    对于您的具体情况,您需要the following key function

    def key(x):
        x = ''.join([i for i in x if i.isdigit() or i=='_'])
        return '{1:{f}{a}10}_{2:{f}{a}10}_{3:{f}{a}10}'.format(*x.split('_'), f='0', a='>')
    
    d = mysort(data, 'MyColumn', key)
    

    【讨论】:

    • 谢谢。仍然无法正确排序... 1-指向 [:,col] 2-说“IndexError:太多索引” 2-我将 [:,col] 更改为 [:][col] ,它似乎可以完成这项工作,但我不知道在哪里插入 key=natural_keys 以正确排序。
    • 我可能会添加...我不知道如何检查我是否有 np.ndarray 或 np.matrix!我用 np.loadtxt 加载了一个文本文件
    • 使用np.loadtxt()加载时您有一个np.ndarray
    • @Sara 它应该可以工作,您不需要natural_keys...您只需使用col 告知您要对哪一列进行排序,记住0 是第一列
    • 对于较大的作业编号,只需在格式化字符串中使用更多位数,例如 '{1:{f}{a}10}_{2:{f}{a}10}_{3:{f}{a}10}'... 可以处理高达 9999999999 的作业编号
    猜你喜欢
    • 1970-01-01
    • 2018-04-24
    • 2021-06-29
    • 2014-06-02
    • 2021-03-08
    • 1970-01-01
    • 2012-06-11
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多