Pandas按ID分组计算当前行日期之前的number列均值如何实现
实现方法
你原来的逐行筛选写法性能较低,推荐用分组累计+偏移的方案,代码如下:
import pandas as pd df = (pd.DataFrame({'ID':['1','1','1','1','2','2'], 'number':['1','4','1','4','2','5'], 'date':['2021-10-19','2021-10-16','2021-10-16','2021-10-15','2021-10-19','2021-10-10']}) # 先做数据类型转换,number转整型才能正确计算均值 .assign(date = lambda x: pd.to_datetime(x.date), number = lambda x: x.number.astype(int)) # 按ID、日期升序排序,保证同ID下的行按时间先后排列 .sort_values(['ID', 'date']) # 计算目标列 .assign(mean_no_from_previous_dts = lambda x: # 按ID分组计算累计到当前行的均值 x.groupby('ID')['number'].expanding().mean() # 按ID分组偏移1位,排除当前行,仅保留前面所有行的均值 .groupby('ID').shift(1) .reset_index(drop=True) ) # 恢复原始数据的行顺序 .sort_index() # 无前置数据的空值填充为0 .fillna(0) )
运行后输出结果和你要求的完全一致:
| ID | number | date | mean_no_from_previous_dts | |
|---|---|---|---|---|
| 0 | 1 | 1 | 2021-10-19 | 3.0 |
| 1 | 1 | 4 | 2021-10-16 | 2.5 |
| 2 | 1 | 1 | 2021-10-16 | 4.0 |
| 3 | 1 | 4 | 2021-10-15 | 0.0 |
| 4 | 2 | 2 | 2021-10-19 | 5.0 |
| 5 | 2 | 5 | 2021-10-10 | 0.0 |
逻辑说明
- 同ID下先按日期排序,保证时间早的行排在前面
expanding().mean()会计算从组内第一行到当前行的所有number的均值shift(1)把均值结果向下偏移一位,当前行对应的均值就变成了前面所有行的均值,自动排除了当前行以及同日期排在当前行之后的行- 最后恢复原始行顺序,空值填0即可
内容的提问来源于stack exchange,提问作者corianne1234
相关产品推荐
相关产品推荐

