如何在pandas DataFrame中按星期分组计算收入累计和
pandas按星期维度分组计算收入累计和实现方案
原始示例数据
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt df = pd.DataFrame({'day': ['Mon','Tue','Wed', 'Mon', 'Tue', 'Wed'], 'date': ['2002-01-02', '2002-01-03', '2002-01-04', '2002-01-08', '2002-01-09', '2002-01-10'], 'income': [40, 60, 40, 100, 55, 32] })
过往写法的问题
- 直接对整列
income调用cumsum():会对所有行做全局累加,无法实现不同星期分别累计的效果,配套绘图代码还存在括号位置错误、星期值不匹配(原始数据是Mon缩写,代码写了Monday全称)的语法问题:
# 错误写法 df['cum_income_by_day'] = df['income'].cumsum() Monday = df[df['day']] == 'Monday' # 括号位置错误,且值不匹配 sn.lineplot(data = Monday, x="Date", y="cum_income_by_day")
- 单独筛选单星期数据再赋值回原表:会触发
setting with copy警告,且非目标星期的行累计值为空,结果完全失真:
# 错误写法 Monday = df[df['day'] == 'Monday'] df['cum_income_by_day'] = Monday['income'].cumsum()
- 调用
groupby仅得到单个累计值、for循环实现失败:核心原因是没有在分组对象上调用逐行转换的累计逻辑。
正确实现代码
直接按day列分组后,对每组的income列调用cumsum(),将结果直接赋值给新列即可,无需循环、无需单独拆分每个星期的数据,也不会触发副本警告:
# 核心计算逻辑:分组后计算组内累计和 df['cum_income_by_day'] = df.groupby('day')['income'].cumsum() # 可选:将date列转为时间格式,避免绘图时x轴排序错乱 df['date'] = pd.to_datetime(df['date'])
计算完成后的DataFrame结果如下,完全符合同星期单独累计的需求:
| day | date | income | cum_income_by_day |
|---|---|---|---|
| Mon | 2002-01-02 | 40 | 40 |
| Tue | 2002-01-03 | 60 | 60 |
| Wed | 2002-01-04 | 40 | 40 |
| Mon | 2002-01-08 | 100 | 140 |
| Tue | 2002-01-09 | 55 | 115 |
| Wed | 2002-01-10 | 32 | 72 |
修正后的seaborn绘图代码
通过hue参数指定按星期区分线条,即可一次性绘制所有星期的累计收入趋势:
sns.lineplot(data=df, x="date", y="cum_income_by_day", hue="day") plt.show()
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

