You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pandas计算月度支出移动平均及resample报错问题咨询

解决月度平均支出及6个月移动平均的绘制问题

首先,你遇到的resample错误核心原因很明确:resample方法要求DataFrame/Series的索引是DatetimeIndex、TimedeltaIndex或PeriodIndex类型,而你的当前索引是默认的RangeIndex(数字索引)——哪怕Date_of_event是datetime列也没用,resample是基于索引工作的,不是普通列。

下面给你两种可行的解决方案,从数据处理到绘图一步到位:

方案一:使用resample(推荐,更简洁)

步骤1:标准化日期列并设置为索引

先确保你的日期列是datetime类型(你说已经能使用dt方法,这一步可能已经完成,但还是可以加一行确认),然后将其设置为DataFrame的索引:

import pandas as pd

# 确保日期列是datetime类型(如果还没转换的话)
df['Date_of_event'] = pd.to_datetime(df['Date_of_event'])
# 将日期列设置为DataFrame的索引
df = df.set_index('Date_of_event')

步骤2:计算月度平均支出

现在索引是DatetimeIndex,就可以正常使用resample了:

# 按日历月重采样,计算月度平均支出
monthly_avg_exp = df['expenditure'].resample('M').mean()

这里'M'表示按自然月聚合,mean()会自动计算每个月的支出平均值。

步骤3:计算6个月移动平均

用rolling方法实现滚动平均:

# 计算连续6个月份的滚动平均(window=6表示取最近6个月的数据计算均值)
six_month_rolling_avg = monthly_avg_exp.rolling(window=6).mean()

方案二:使用groupby按年月分组

如果不想修改DataFrame的索引,也可以提取年月作为分组键来计算月度平均:

# 提取年月信息,转为Period类型(保证时间顺序的一致性)
df['year_month'] = df['Date_of_event'].dt.to_period('M')
# 按年月分组计算平均支出
monthly_avg_exp = df.groupby('year_month')['expenditure'].mean()
# 必须排序,否则移动平均会因为时间乱序出错
monthly_avg_exp = monthly_avg_exp.sort_index()
# 同样计算6个月移动平均
six_month_rolling_avg = monthly_avg_exp.rolling(window=6).mean()

用Seaborn/Matplotlib绘图

用Matplotlib绘制:

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
# 绘制月度平均支出
monthly_avg_exp.plot(marker='o', label='月度平均支出')
# 绘制6个月移动平均
six_month_rolling_avg.plot(marker='s', label='6个月移动平均')

plt.title('月度平均支出与6个月移动平均')
plt.xlabel('年月')
plt.ylabel('支出金额')
plt.legend()
plt.xticks(rotation=45)
plt.tight_layout()  # 自动调整布局,避免标签被截断
plt.show()

用Seaborn绘制(更美观):

需要先将Series转为DataFrame,适配Seaborn的输入格式:

import seaborn as sns
import matplotlib.pyplot as plt

# 将数据整理为长格式DataFrame
plot_data = pd.DataFrame({
    '年月': monthly_avg_exp.index.astype(str),  # 将Period转为字符串,方便x轴显示
    '月度平均支出': monthly_avg_exp.values,
    '6个月移动平均': six_month_rolling_avg.values
}).melt(id_vars='年月', var_name='指标', value_name='支出金额')

plt.figure(figsize=(10, 6))
sns.lineplot(data=plot_data, x='年月', y='支出金额', hue='指标', marker='o')

plt.title('月度平均支出与6个月移动平均')
plt.xlabel('年月')
plt.ylabel('支出金额')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

额外说明:

你之前的错误代码df['Date_of_event'] = df['Date_time'].resample('M')有两个问题:

  1. 列名可能写错了(你的数据里是Date_of_event,不是Date_time);
  2. resample不能直接赋值给普通列,它需要作用在带时间索引的Series/DataFrame上,返回的是重采样后的结果,不是修改原列。

内容的提问来源于stack exchange,提问作者Calvin77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:04:31