【问题标题】:How to sort dataframe in month+year order?如何按月+年的顺序对数据框进行排序?
【发布时间】:2021-10-12 18:54:39
【问题描述】:

我是 python 新手,我正在尝试解决以月+年格式对 df 进行排序的问题,而我的原始数据如下所示: (重新编辑:不好意思,查了一下原来的df,月份列其实是这样的:Aug, Jul, Jul, Jun。不是数字格式)

ID       year   month      ym
1        2018    Aug    Aug 2018
2        2018    Jul    Jul 2018
3        2019    Jul    Jul 2019
4        2019    Jun    Jun 2018

我的思路是①按照年份拆分成两个df,然后②对月份排序,最后③合并。但是有一些问题:

对于①,不知道怎么用groupby进行拆分;

对于②,我尝试这样排序,成功了,但是看起来只是临时排序:

sort_order=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
df.index = pd.CategoricalIndex(df['month'], categories=sort_order, ordered=True)
df.sort_index().reset_index(drop=True)

对于③,我担心因为它是临时排序的,所以我尝试将它们两者合并时会是原始的。

我相信应该有更好的方法来解决这个问题。谁能给个提示,或者指出我有什么错吗?谢谢!!

【问题讨论】:

    标签: python pandas dataframe date sorting


    【解决方案1】:

    根据您的示例(假设您的数据框名为 df),只需执行以下操作:

    df = df.sort_values(["year", "month"])
    

    这就是结果:

        year    month   ym
    1   2018    7   Jul 2018
    0   2018    8   Aug 2018
    3   2019    6   Jun 2018
    2   2019    7   Jul 2019
    

    编辑请求:

    所以要将月份字符串转换为数字,只需这样做: 创建字典:

    months = {
        "Jun": 6, 
        "Jul":7 ,
        "Aug": 8, 
        ....
    }
    

    等等, 然后只需创建一个函数将月份转换为这样的整数:

    def transform(month):
        return months[month]
    

    然后将其应用于您的 df

    df["month"] = df["month].apply(transform)
    

    通过这种方式,您将在月份列中拥有一个包含整数而不是字符串的数据框

    【讨论】:

    • 我将赋值添加回df,因为我认为这是 OP 的主要问题(它成功了,但它看起来只是暂时排序
    • 谢谢分享!!它有很大帮助!抱歉,我还有一个问题,我刚刚检查了月份列实际上不是数字格式,就像:六月,八月,六月,七月。这样我如何将它们转换为数字?提前谢谢!
    • 我已经编辑了我的答案,检查它(只需将月份转换为如上所述的整数,然后应用相同的过程对其进行排序,)
    • 感谢您的再次热心回答!运行后出现密钥错误 7. 这是否意味着我尝试访问不在 dic 中的密钥。?但是运行 dic。和定义。功能都很好。有没有我可能错的地方?提前谢谢!
    • 抱歉回复晚了!它已经过去了!非常感谢!
    【解决方案2】:

    你可以用YYYY-mm组成一个复合字符串,然后按照这个顺序排序。

    我们首先将MMM YYYY 字符串格式的ym 列转换为pd.to_datetime 的日期时间格式,然后使用dt.strftime 格式化YYYY-mm 中的日期字符串。这种格式字符串以年开头,然后是月份,适合按时间顺序排序。

    df['YYYY-mm'] = pd.to_datetime(df['ym'], format='%b %Y').dt.strftime('%Y-%m')
    
    df = df.sort_values('YYYY-mm')
    

    结果:

    print(df)
    
    
       ID  year month        ym  YYYY-mm
    3   4  2019   Jun  Jun 2018  2018-06
    1   2  2018   Jul  Jul 2018  2018-07
    0   1  2018   Aug  Aug 2018  2018-08
    2   3  2019   Jul  Jul 2019  2019-07
    

    【讨论】:

    • 是的,我能理解!感谢您的帮助!
    【解决方案3】:

    如果你想使用日期,我建议你使用真实的DatetimeIndex

    df = df.set_index(pd.to_datetime(df['ym']).rename('datetime'))
    print(df)
    
    # Output:
                ID  year  month        ym
    datetime                             
    2018-08-01   1  2018      8  Aug 2018
    2018-07-01   2  2018      7  Jul 2018
    2019-07-01   3  2019      7  Jul 2019
    2018-06-01   4  2019      6  Jun 2018
    

    现在您可以轻松地对数据框进行排序

    >>> df.sort_index(ascending=False)
                ID  year  month        ym
    datetime                             
    2019-07-01   3  2019      7  Jul 2019
    2018-08-01   1  2018      8  Aug 2018
    2018-07-01   2  2018      7  Jul 2018
    2018-06-01   4  2019      6  Jun 2018
    

    过滤你的数据框:

    >>> df[df.index > "2018-06"]
                ID  year  month        ym
    datetime                             
    2018-08-01   1  2018      8  Aug 2018
    2018-07-01   2  2018      7  Jul 2018
    2019-07-01   3  2019      7  Jul 2019
    

    按年份分组:

    >>>  df.groupby(df.index.year)['ID'].sum()
    datetime
    2018    7
    2019    3
    Name: ID, dtype: int64
    

    【讨论】:

    • 有道理!谢谢你的帮助!
    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多