【问题标题】:sort dataFrame index containing string and number对包含字符串和数字的数据帧索引进行排序
【发布时间】:2018-04-27 02:45:00
【问题描述】:

我有一个数据框,其中索引值是由下划线分隔的字符串和数字的混合体。

    sub_int1_ICA_int2  # 

我想先使用 int1 对列索引进行排序,然后再使用 int2 预期的输出是:

    sub_1_ICA_1
    sub_1_ICA_2
    sub_1_ICA_3
    ...........
    sub_2_ICA_1
    sub_2_ICA_2
    ...........

我尝试使用在许多帖子中看到的 convert_numeric,但出现错误

     X.convert_objects(convert_numeric=True).sort_values(['id] , ascending=[True], inplace=True)
    >>(KeyError: 'id')

任何帮助都会很好!

【问题讨论】:

    标签: python-2.7 pandas dataframe


    【解决方案1】:

    使用reindex by sorted list 通过自定义函数和dictionary 元组:

    print (df)
                  a
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    
    
    a = df.index.tolist()
    b = {}
    for x in a:
        i = x.split('_')
        b[x] = ((int(i[1]), int(i[-1])))
    print (b)
    {'sub_1_ICA_10': (1, 10), 'sub_1_ICA_11': (1, 11), 
    'sub_1_ICA_1': (1, 1), 'sub_2_ICA_2': (2, 2),
     'sub_1_ICA_0': (1, 0), 'sub_1_ICA_12': (1, 12), 
     'sub_1_ICA_3': (1, 3), 'sub_1_ICA_2': (1, 2),
     'sub_2_ICA_1': (2, 1)}
    
    c = sorted(a, key=lambda x: b[x])
    print (c)
    ['sub_1_ICA_0', 'sub_1_ICA_1', 'sub_1_ICA_2', 'sub_1_ICA_3', 
    'sub_1_ICA_10', 'sub_1_ICA_11', 'sub_1_ICA_12', 'sub_2_ICA_1', 'sub_2_ICA_2']
    

    df = df.reindex(c)
    print (df)
                  a
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    

    另一个纯熊猫解决方案:

    #create MultiIndex by split index, convert to DataFrame
    df1 = df.index.str.split('_', expand=True).to_frame()
    #set columns and index to original df
    df1.columns = list('abcd')
    df1.index = df.index
    #convert columns to int and sort
    df1[['b','d']] = df1[['b','d']].astype(int)
    df1 = df1.sort_values(['b','d'])
    print (df1)
                    a  b    c   d
    sub_1_ICA_0   sub  1  ICA   0
    sub_1_ICA_1   sub  1  ICA   1
    sub_1_ICA_2   sub  1  ICA   2
    sub_1_ICA_3   sub  1  ICA   3
    sub_1_ICA_10  sub  1  ICA  10
    sub_1_ICA_11  sub  1  ICA  11
    sub_1_ICA_12  sub  1  ICA  12
    sub_2_ICA_1   sub  2  ICA   1
    sub_2_ICA_2   sub  2  ICA   2
    
    df = df.reindex(df1.index)
    print (df)
                  a
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    

    最后一个版本是natsort:

    from natsort import natsorted
    
    df = df.reindex(natsorted(df.index))
    print (df)
                  a
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    

    编辑:

    如果重复值则通过拆分创建新列,转换为int,排序并返回:

    print (df)
                  a
    sub_1_ICA_0   4
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    
    df.index = df.index.str.split('_', expand=True)
    df = df.reset_index()
    df[['level_1','level_3']] = df[['level_1','level_3']].astype(int)
    df = df.sort_values(['level_1','level_3']).astype(str)
    
    df = df.set_index(['level_0','level_1','level_2','level_3'])
    df.index = df.index.map('_'.join)
    
    print (df)
    
                  a
    sub_1_ICA_0   4
    sub_1_ICA_0   4
    sub_1_ICA_1   8
    sub_1_ICA_2   6
    sub_1_ICA_3   6
    sub_1_ICA_10  7
    sub_1_ICA_11  3
    sub_1_ICA_12  2
    sub_2_ICA_1   1
    sub_2_ICA_2   3
    

    【讨论】:

    • 非常感谢,杰兹瑞尔!第一个代码在最初没有默认索引 (0,1,2) 的数据框中完美运行。但是,当我在将索引设置为“id”列(使用 set_index)的数据框中使用它时,出现错误“无法从重复轴重新索引”。当我检查 print(c) 时,我可以看到所有索引值都重复了几次。有什么想法吗?
    • 谢谢,但我不应该有重复索引的问题!
    • 那么问题出在数据上,通过print (df[df.index.duplicated(keep=False)])检查重复的索引值
    • 是的!有重复的条目可能是因为我通过 concat 构造了 df。有没有办法删除重复的索引?
    • 如果不需要索引中的数据,最好是df = df.reset_index(drop=True)
    猜你喜欢
    • 2020-12-21
    • 2019-05-26
    • 1970-01-01
    • 2016-10-28
    • 2021-08-12
    • 2020-02-18
    • 2016-01-23
    相关资源
    最近更新 更多