Pandas多列GroupBy+滚动窗口新增列问题:多分组返回全NaN
解决方案:按UserID+IBAN分组统计24小时内交易数据
核心问题分析
你遇到的全NaN问题,大概率是以下几个原因导致的:
- Timestamp未转换为datetime类型,时间窗口参数无法生效
- 分组后未对组内数据按Timestamp排序,滚动窗口按乱序行计算导致逻辑错误
- 多索引处理不当,滚动计算后的结果无法正确映射回原数据集
分步解决代码
1. 数据预处理(类型转换+排序)
首先确保时间字段是datetime格式,且每个(UserID, IBAN)组内的交易按时间排序:
import pandas as pd # 示例数据 data = { 'UserID': [1, 1, 1, 1, 2], 'IBAN': ['DE1234567890', 'DE1234567890', 'DE1234567890', 'FR0987654321', 'DE1234567890'], 'Timestamp': ['2024-01-01 10:00:00', '2024-01-01 15:00:00', '2024-01-02 09:00:00', '2024-01-01 11:00:00', '2024-01-01 12:00:00'], 'Amount': [100, 200, 150, 300, 50] } df = pd.DataFrame(data) # 转换Timestamp为datetime类型(关键步骤) df['Timestamp'] = pd.to_datetime(df['Timestamp']) # 按(UserID, IBAN)分组后,组内按时间排序 df_sorted = df.groupby(['UserID', 'IBAN'], group_keys=False).apply(lambda x: x.sort_values('Timestamp'))
2. 滚动窗口计算24小时内交易统计
使用rolling('24h')基于时间窗口计算,并通过reset_index处理多索引,确保结果正确映射:
# 统计24小时内交易次数 df_sorted['24h_trans_count'] = df_sorted.groupby(['UserID', 'IBAN'])['Amount']\ .rolling('24h', on='Timestamp').count()\ .reset_index(level=[0,1], drop=True) # 统计24小时内交易金额总和 df_sorted['24h_total_amount'] = df_sorted.groupby(['UserID', 'IBAN'])['Amount']\ .rolling('24h', on='Timestamp').sum()\ .reset_index(level=[0,1], drop=True)
最终输出结果
处理后的数据如下:
| UserID | IBAN | Timestamp | Amount | 24h_trans_count | 24h_total_amount |
|---|---|---|---|---|---|
| 1 | DE1234567890 | 2024-01-01 10:00:00 | 100 | 1.0 | 100.0 |
| 1 | DE1234567890 | 2024-01-01 15:00:00 | 200 | 2.0 | 300.0 |
| 1 | DE1234567890 | 2024-01-02 09:00:00 | 150 | 2.0 | 350.0 |
| 1 | FR0987654321 | 2024-01-01 11:00:00 | 300 | 1.0 | 300.0 |
| 2 | DE1234567890 | 2024-01-01 12:00:00 | 50 | 1.0 | 50.0 |
关键注意事项
- 时间类型必须正确:如果Timestamp是字符串,
rolling('24h')会识别为字符串窗口,直接返回NaN - 组内必须排序:滚动窗口是按行顺序计算的,时间乱序会导致窗口包含超出24小时范围的数据,或逻辑错误
- 多索引重置:分组滚动后会生成包含(UserID, IBAN)的多索引,必须用
reset_index(level=[0,1], drop=True)去掉多余索引,才能正确赋值回原数据集
内容的提问来源于stack exchange,提问作者paaaaat
相关产品推荐
相关产品推荐

