在Pandas中按组添加某日期之前数值均值的列
解决方案
要实现新增列存储该行日期之前对应团队所有Score的均值,可以通过以下高效步骤处理:
步骤1:准备数据并转换日期类型
先确保日期列是可比较的datetime类型:
import pandas as pd # 构造原数据 df = pd.DataFrame({ 'Date': ['2023-01-02', '2023-01-02', '2023-01-02', '2023-04-07', '2023-04-07', '2023-04-07', '2023-04-07'], 'Team': ['A', 'A', 'B', 'A', 'A', 'B', 'B'], 'Score': [10, 6, 15, 17, 5, 20, 8] }) # 转换Date列为datetime类型 df['Date'] = pd.to_datetime(df['Date'])
步骤2:按团队+日期聚合,计算每日统计量
先聚合每个团队在每个日期的总分数和数据行数,方便后续计算累计均值:
# 按Team和Date分组,统计每日总分和数据量 daily_stats = df.groupby(['Team', 'Date']).agg( total_score=('Score', 'sum'), count=('Score', 'size') ).reset_index()
步骤3:计算团队的历史累计均值(截至当前日期之前)
对每个团队,计算截至前一个日期的累计总分和累计行数,进而得到历史均值:
# 按Team分组,计算累计总分和累计行数,shift(1)排除当前日期的数据 daily_stats['cum_total'] = daily_stats.groupby('Team')['total_score'].cumsum().shift(1).fillna(0) daily_stats['cum_count'] = daily_stats.groupby('Team')['count'].cumsum().shift(1).fillna(0) # 计算历史均值,处理除数为0的情况(团队第一个日期无历史数据) daily_stats['prev_avg'] = daily_stats.apply( lambda x: x['cum_total'] / x['cum_count'] if x['cum_count'] != 0 else None, axis=1 )
步骤4:将均值映射回原表
把计算好的历史均值合并到原数据中,得到最终结果:
# 合并回原数据表 df = df.merge(daily_stats[['Team', 'Date', 'prev_avg']], on=['Team', 'Date'], how='left')
最终结果
处理后的表格如下:
| Date | Team | Score | prev_avg |
|---|---|---|---|
| 2023-01-02 | A | 10 | None |
| 2023-01-02 | A | 6 | None |
| 2023-01-02 | B | 15 | None |
| 2023-04-07 | A | 17 | 8.0 |
| 2023-04-07 | A | 5 | 8.0 |
| 2023-04-07 | B | 20 | 15.0 |
| 2023-04-07 | B | 8 | 15.0 |
这个结果完全符合需求:2023-04-07的Team A行,历史均值为(10+6)/2=8;Team B的历史均值为15。
内容的提问来源于stack exchange,提问作者gunit25
相关产品推荐
相关产品推荐

