如何在pandas中使用pd.Grouper实现多时间单位组合的数据分组
pandas多时间单位组合分组实现方案
问题原因
pandas的freq参数不支持直接拼接可变长度日历偏移量(比如月M、年Y)和其他时间单位,因为月份的实际天数随日历变化,无法直接转换为固定时长,所以'3M 5D'这类写法会直接报错或不生效。
通用解决方案
通过自定义DateOffset计算分组区间的方式实现,兼容任意多时间单位组合(包括月、年这类可变长度单位),完整可运行代码基于你提供的示例数据编写:
import pandas as pd from pandas import Timestamp # 示例数据 df = pd.DataFrame({ 'timestamp' : [ Timestamp('2017-01-01 12:00:00'), Timestamp('2017-02-06 12:00:00'), Timestamp('2017-03-11 12:00:00'), Timestamp('2017-04-16 12:00:00'), Timestamp('2017-05-01 12:00:00'), Timestamp('2017-06-18 12:00:00'), Timestamp('2017-07-01 12:00:00'), ], 'values': [1,2,3,4,5,6,7], 'cols': ['foo', 'bar', 'baz', 'blah', 'foo', 'bar', 'baz']} ) # 定义自定义周期,可自由组合时间单位,示例为3个月零5天 custom_period = pd.DateOffset(months=3, days=5) # 取时间列最小值作为分组起始基准,也可手动指定固定日期 start_base = df['timestamp'].min() # 计算每个时间点所属的分组标签 df['group_label'] = df['timestamp'].apply( lambda x: start_base + ((x - start_base) // custom_period) * custom_period ) # 按自定义分组执行pivot操作 pivot = pd.pivot_table(df, index='group_label', columns='cols', values='values')
补充说明
- 如果你的时间单位都是固定时长(比如天、小时、分钟,不含月、年),可以直接用Timedelta拼接,写法更简单:
freq='3D5H'(代表3天5小时),直接传入pd.Grouper的freq参数即可生效。 - 自定义周期可任意扩展,比如
pd.DateOffset(years=1, months=2, days=10, hours=8)即可实现1年2个月10天8小时的分组周期。
内容的提问来源于stack exchange,提问作者David Jay Brady
相关产品推荐
相关产品推荐

