【问题标题】:How to sort multiindex column month names?如何对多索引列月份名称进行排序?
【发布时间】:2021-07-17 10:30:27
【问题描述】:

我有这个多索引df

                       YEARS_TMAX TMAX YEARS_TMAX TMAX  YEARS_TMAX
MONTH                       April April    August August  December .....
CODE   NAME                                                   
000130 RICA PLAYA          21.0  31.5      21.0   21.5      22.0
000132 PUERTO PIZARRO      12.0  33.8      12.0   32.4      11.0
000134 PAPAYAL             23.0  33.2      22.0   22.4      21.0
000135 EL SALTO            22.0  33.6      23.0   22.8      22.0
000136 CAÑAVERAL           16.0  32.7      15.0   33.1      11.0
                        ...   ...       ...    ...       ...
158317 SUSAPAYA            19.0  17.6      19.0   17.3      21.0
158321 PALCA               16.0  19.3      17.0   19.8      16.0
158323 TALABAYA            12.0  17.6      13.0   17.5      13.0
158326 CAPAZO              17.0  13.6      17.0   13.0      19.0
158328 PAUCARANI           14.0  13.3      13.0   11.9      15.0

我想按月份名称(首先是 TMAX 列)对列进行排序,如下所示:

                           TMAX YEARS_TMAX TMAX YEARS_TMAX  TMAX
MONTH                      January January February February March .....
CODE   NAME                                                   
000130 RICA PLAYA          22.0  31.5      23.0   27.5      23.0
000132 PUERTO PIZARRO      17.0  32.8      18.0   30.4      18.0
000134 PAPAYAL             25.0  32.2      26.0   28.4      25.0
000135 EL SALTO            26.0  31.6      26.0   26.8      26.0
000136 CAÑAVERAL           16.0  32.7      18.0   31.1      15.0
                        ...   ...       ...    ...       ...
158317 SUSAPAYA            19.0  17.6      19.0   17.3      21.0
158321 PALCA               16.0  19.3      17.0   19.8      16.0
158323 TALABAYA            12.0  17.6      13.0   17.5      13.0
158326 CAPAZO              17.0  13.6      17.0   13.0      19.0
158328 PAUCARANI           14.0  13.3      13.0   11.9      15.0

所以我写了这段代码: 来源:Sort "Date" in Multi-Index

dates = pd.to_datetime(df.columns.get_level_values(1), format='%B')
df.columns = [df.columns.get_level_values(0), dates]
df = df.sort_index(axis=1, level=1)

要按月份对列进行排序,但 dates 没有创建月份名称,dates 正在创建随机日期。 我该如何解决这个问题?

提前致谢。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    通过从 calendar.month_name 创建有序 dtype 来使用 CategoricalDtype,这将确保按排序正确排序。

    month_dtype = pd.CategoricalDtype(categories=list(month_name), ordered=True)
    df.columns = [df.columns.get_level_values(0),
                  df.columns.get_level_values(1).astype(month_dtype)]
    df = df.sort_index(axis=1, level=[1, 0])
    

    示例数据和导入:

    from calendar import month_name
    
    import pandas as pd
    
    df = pd.DataFrame(
        [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]],
        columns=pd.MultiIndex.from_product([
            ['YEARS_TMAX', 'TMAX'],
            ['March', 'January', 'February']
        ])
    )
    

    df 排序前:

      YEARS_TMAX                   TMAX                 
           March January February March January February
    0          1       2        3     4       5        6
    1          7       8        9    10      11       12
    

    df 排序后:

         TMAX YEARS_TMAX     TMAX YEARS_TMAX  TMAX YEARS_TMAX
      January    January February   February March      March
    0       5          2        6          3     4          1
    1      11          8       12          9    10          7
    

    日期时间方法也可以,但需要使用 DatetimeIndex.strftime 转换回字符串:

    df.columns = [df.columns.get_level_values(0),
                  pd.to_datetime(df.columns.get_level_values(1), format='%B')]
    df = df.sort_index(axis=1, level=[1, 0])
    
    # convert back to strings
    df.columns = [df.columns.get_level_values(0),
                  df.columns.get_level_values(1).strftime('%B')]
    

    df:

         TMAX YEARS_TMAX     TMAX YEARS_TMAX  TMAX YEARS_TMAX
      January    January February   February March      March
    0       5          2        6          3     4          1
    1      11          8       12          9    10          7
    

    这种方法的缺点是第 1 级再次是一个字符串类型,在需要更改排序的任何时候都需要转换它,因为不需要字典顺序。

    【讨论】:

    • 您的答案是正确的,但我还需要先 TMAX 列。就像我展示的第二个df一样。我该怎么做?
    • 已更新。按 1 然后 0 排序。df = df.sort_index(axis=1, level=[1, 0])
    • with: df = df.sort_index(axis=1, level=[1, 0],ascending=[True,False]) 我解决了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2018-06-11
    • 1970-01-01
    • 2013-11-24
    • 2019-03-09
    相关资源
    最近更新 更多