如何用Pandas GroupBy按Reference与时间戳月份聚合数据?解决TypeError
问题描述
我有如下结构的Pandas DataFrame:
| Reference | timestamp | sub_reference | datatype_indicator | figure |
|---|---|---|---|---|
| REF1 | 2022-09-01 | 10 | A | 23.6 |
| REF1 | 2022-09-01 | 48 | B | 25.8 |
| REF1 | 2022-09-02 | 10 | A | 17.4 |
| REF1 | 2022-10-01 | 10 | A | 23.6 |
| REF1 | 2022-10-01 | 48 | B | 25.8 |
| REF1 | 2022-10-02 | 10 | A | 17.4 |
| REF2 | 2022-09-01 | 10 | A | 23.6 |
| REF2 | 2022-09-01 | 48 | B | 25.8 |
| REF2 | 2022-09-02 | 10 | A | 17.4 |
| REF2 | 2022-10-01 | 11 | A | 23.6 |
| REF2 | 2022-10-01 | 47 | B | 25.8 |
| REF2 | 2022-10-02 | 10 | A | 17.4 |
| REF3 | 2022-09-01 | 10 | A | 23.6 |
| REF3 | 2022-09-01 | 48 | B | 25.8 |
| REF3 | 2022-09-02 | 10 | A | 17.4 |
| REF3 | 2022-10-01 | 11 | A | 23.6 |
| REF3 | 2022-10-01 | 47 | B | 25.8 |
| REF3 | 2022-10-02 | 10 | A | 17.4 |
需要按Reference列和timestamp列的月份分组,计算每个Reference-月份组合对应的figure列聚合值。尝试了以下代码,但触发错误:
TypeError: unhashable type: 'Series'
错误代码:
dg = df1.groupby([ pd.Grouper('reference'), pd.Grouper(df1['timestamp'].dt.month) ]).sum() dg.index = dg.index.strftime('%B') print(dg)
解决方案
错误原因分析
pd.Grouper使用方式错误:第二个pd.Grouper直接传入了df1['timestamp'].dt.month这个Series,而pd.Grouper仅支持传入列名或时间频率参数,直接传入Series会触发哈希不可用的报错。- 索引处理错误:分组后的索引是多级结构(Reference+月份),直接调用
strftime会报错,需要单独处理月份层级的格式。
正确实现代码
方法一:用pd.Grouper按时间频率分组
先确保timestamp列为datetime类型,再通过时间频率参数指定按月分组:
# 确保timestamp是datetime类型(若原数据不是则执行此步) df1['timestamp'] = pd.to_datetime(df1['timestamp']) # 分组并聚合figure列 dg = df1.groupby([ 'Reference', pd.Grouper(key='timestamp', freq='M') # freq='M'表示按自然月末分组 ])['figure'].sum() # 将月份索引转换为英文月份名称 dg.index = dg.index.set_levels(dg.index.levels[1].strftime('%B'), level=1) print(dg)
方法二:直接提取月份名称作为分组键
如果不需要保留完整日期,可直接提取月份名称作为分组依据:
df1['timestamp'] = pd.to_datetime(df1['timestamp']) # 按Reference和月份名称分组聚合 dg = df1.groupby([ 'Reference', df1['timestamp'].dt.month_name() # 直接生成英文月份名称 ])['figure'].sum() print(dg)
输出示例
两种方法都会得到类似如下的结果:
Reference timestamp REF1 September 66.8 October 66.8 REF2 September 66.8 October 66.8 REF3 September 66.8 October 66.8 Name: figure, dtype: float64
内容的提问来源于stack exchange,提问作者Ryan1234
相关产品推荐
相关产品推荐

