如何在Pandas中创建包含两日滚动平均值的透视表
解决方案
首先要注意你的原始DataFrame里Ratings列存在字符串类型的"NaN",这会导致后续均值计算出错,所以第一步需要先把这些值转换成真正的缺失值,并将列转为数值类型。接下来我们分步骤实现你的需求:
步骤1:数据预处理
import pandas as pd import numpy as np # 原始数据 df = pd.DataFrame({ "Date":["2021-01-01", "2021-01-01", "2021-01-01", "2021-01-02", "2021-01-02", "2021-01-02", "2021-01-02", "2021-01-03", "2021-01-03", "2021-01-03"], "Name":["Tim", "Tim", "Ben", "Leo", "Tim", "Ben", "Leo", "Leo", "Ben", "Tim"], "Ratings":[9.0, 8.0, 5.0, 3.0, "NaN", "NaN", 6, 5, 3, 5] }) # 处理Ratings列:替换字符串"NaN"为真正的缺失值,并转为数值类型 df["Ratings"] = pd.to_numeric(df["Ratings"], errors="coerce")
步骤2:生成每日均值透视表
这一步和你之前的操作类似,得到每个日期、每个用户的当日平均评分:
daily_mean = df.pivot_table( values='Ratings', index='Date', columns='Name', aggfunc='mean' )
此时daily_mean的结果是:
| Date | Ben | Leo | Tim |
|---|---|---|---|
| 2021-01-01 | 5 | NaN | 8.5 |
| 2021-01-02 | NaN | 4.5 | NaN |
| 2021-01-03 | 3 | 5 | 5 |
步骤3:计算两日滚动平均值
对透视表的每一列应用窗口大小为2的滚动平均,设置min_periods=1确保第一天没有前序数据时保留原值:
rolling_2d_mean = daily_mean.rolling(window=2, min_periods=1).mean()
步骤4:调整结果格式(匹配你的期望输出)
我们可以填充缺失值为"NaN",并调整小数位数:
# 调整小数位数,同时将NaN转为字符串"NaN" result = rolling_2d_mean.round(2).replace({np.nan: "NaN"}).reset_index()
最终result的输出如下:
| Date | Ben | Leo | Tim |
|---|---|---|---|
| 2021-01-01 | 5 | NaN | 8.5 |
| 2021-01-02 | NaN | 4.5 | 8.5 |
| 2021-01-03 | 4 | 4.75 | 5 |
补充说明
- 你期望的Leo第三日值是4.66,实际计算应为(4.5+5)/2=4.75,可能是你期望中的笔误;Ben第二日的均值是(5+NaN)/2=NaN,和你期望的5略有不同,因为原始数据中Ben在2021-01-02没有有效评分,所以两日滚动平均会是缺失值。
- 如果需要将缺失值填充为0(像你之前代码里的
fill_value=0),可以在pivot_table时加上,但这样会影响滚动平均的结果,比如Ben第二日的均值会变成(5+0)/2=2.5,需要根据你的实际需求选择。
内容的提问来源于stack exchange,提问作者fjurt
相关产品推荐
相关产品推荐

