【问题标题】:Sort DataFrame index that has a string and number对具有字符串和数字的 DataFrame 索引进行排序
【发布时间】:2014-05-06 11:24:47
【问题描述】:

我的df DataFrame 索引如下所示:

Com_Lag_01
Com_Lag_02
Com_Lag_03
Com_Lag_04
Com_Lag_05
Com_Lag_06
Com_Lag_07
Com_Lag_08
Com_Lag_09
Com_Lag_10
Com_Lag_101
Com_Lag_102
Com_Lag_103
...
Com_Lag_11
Com_Lag_111
Com_Lag_112
Com_Lag_113
Com_Lag_114
...
Com_Lag_12
Com_Lag_120
...
Com_Lag_13
Com_Lag_14
Com_Lag_15

我想对该索引进行排序,使数字从Com_Lag_1 变为Com_Lag_120。如果我使用df.sort_index(),我会得到和上面一样的东西。有关如何正确排序此索引的任何建议?

【问题讨论】:

  • 你必须对最后一个 '_' 进行反向查找,然后转换为 int 并按此数字排序

标签: python pandas


【解决方案1】:

人们可以尝试这样的事情,通过对索引的编号版本执行排序

import pandas as pd
# Create a DataFrame example
df = pd.DataFrame(\
    {'Year': [1991 ,2004 ,2001 ,2009 ,1997],\
    'Age': [27 ,25 ,22 ,34 ,31],\
    },\
    index = ['Com_Lag_1' ,'Com_Lag_12' ,'Com_Lag_3' ,'Com_Lag_24' ,'Com_Lag_5'])

# Add of a column containing a numbered version of the index
df['indexNumber'] = [int(i.split('_')[-1]) for i in df.index]
# Perform sort of the rows
df.sort(['indexNumber'], ascending = [True], inplace = True)
# Deletion of the added column
df.drop('indexNumber', 1, inplace = True)


编辑 2017 - V1

为了避免 SettingWithCopyWarning:

df = df.assign(indexNumber=[int(i.split('_')[-1]) for i in df.index])

Edit 2017 - V2 for Pandas 版本 0.21.0

import pandas as pd
print(pd.__version__)
# Create a DataFrame example
df = pd.DataFrame(\
    {'Year': [1991 ,2004 ,2001 ,2009 ,1997],\
    'Age': [27 ,25 ,22 ,34 ,31],\
    },\
    index = ['Com_Lag_1' ,'Com_Lag_12' ,'Com_Lag_3' ,'Com_Lag_24' ,'Com_Lag_5'])

df.reindex(index=df.index.to_series().str.rsplit('_').str[-1].astype(int).sort_values().index)

【讨论】:

    【解决方案2】:

    没有新列的解决方案,DataFrame.reindex by index of sorted Series

    a = df.index.to_series().str.rsplit('_').str[-1].astype(int).sort_values()
    print (a)
    Com_Lag_1      1
    Com_Lag_3      3
    Com_Lag_5      5
    Com_Lag_12    12
    Com_Lag_24    24
    dtype: int32
    
    df = df.reindex(index=a.index)
    print (df)
                Age  Year
    Com_Lag_1    27  1991
    Com_Lag_3    22  2001
    Com_Lag_5    31  1997
    Com_Lag_12   25  2004
    Com_Lag_24   34  2009
    

    但如果需要重复值,请添加新列:

    df = pd.DataFrame(\
        {'Year': [1991 ,2004 ,2001 ,2009 ,1997],\
        'Age': [27 ,25 ,22 ,34 ,31],\
        },\
        index = ['Com_Lag_1' ,'Com_Lag_12' ,'Com_Lag_3' ,'Com_Lag_24' ,'Com_Lag_12'])
    
    print (df)
                Age  Year
    Com_Lag_1    27  1991
    Com_Lag_12   25  2004
    Com_Lag_3    22  2001
    Com_Lag_24   34  2009
    Com_Lag_12   31  1997
    
    df['indexNumber'] = df.index.str.rsplit('_').str[-1].astype(int)
    df = df.sort_values(['indexNumber']).drop('indexNumber', axis=1)
    print (df)
                Age  Year
    Com_Lag_1    27  1991
    Com_Lag_3    22  2001
    Com_Lag_12   25  2004
    Com_Lag_12   31  1997
    Com_Lag_24   34  2009
    

    【讨论】:

      【解决方案3】:

      另一种解决方案是

          df.sort_index(key=lambda x: (x.to_series().str[8:].astype(int)), inplace=True)
      

      8来自数值开始的位置

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-27
        • 2016-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-02
        • 2019-04-19
        • 2013-03-09
        相关资源
        最近更新 更多