Pandas循环计算日期对应%Change累计值与均值结果异常排查
问题:计算每日%Change累计值与均值时列表结果重复
原始数据与需求
有如下DataFrame:
Date year month day Week days % Change 0 2020-01-02 2020 1 2 Thursday NaN 1 2020-01-03 2020 1 3 Friday -0.71 2 2020-01-06 2020 1 6 Monday 0.35 3 2020-01-07 2020 1 7 Tuesday -0.28 4 2020-01-08 2020 1 8 Wednesday 0.49 .. ... ... ... ... ... ... 500 2021-12-27 2021 12 27 Monday 1.38 501 2021-12-28 2021 12 28 Tuesday -0.10 502 2021-12-29 2021 12 29 Wednesday 0.14 503 2021-12-30 2021 12 30 Thursday -0.30 504 2021-12-31 2021 12 31 Friday -0.26
需求:针对1-31日,计算对应% Change列的累计值与均值,存入一个31行2列的新DataFrame。
尝试的代码与问题
以下是验证计算的代码:
Range_Days = [*range(1, 32, 1)] Perf=Range_Days Perf_mean=Range_Days i=0 for x in Range_Days: uno=Ticker_Ch.loc[Ticker_Ch["day"]==x] Perf_mean[i]=Ticker_Ch.loc[Ticker_Ch["day"]==x,'% Change'].mean().round(4) Perf[i]=Ticker_Ch.loc[Ticker_Ch["day"]==x,'% Change'].sum().round(4) i=i+1 print(Perf_mean) print(Perf) #Perf_day_s_month=pd.DataFrame(Perf,Perf_mean)
输出的Perf_mean和Perf结果完全相同:
[*********************100%***********************] 1 of 1 completed [1.89, 13.5, -4.71, 5.57, 12.23, 8.94, 5.89, 6.28, -2.14, 3.6, -11.34, -7.87, 7.87, 7.12, 5.52, -9.64, 5.58, -9.13, -3.47, -2.26, -1.33, 6.1, -0.86, 9.27, 0.26, 2.8, -7.03, -1.54, 7.17, -1.22, -2.21] [1.89, 13.5, -4.71, 5.57, 12.23, 8.94, 5.89, 6.28, -2.14, 3.6, -11.34, -7.87, 7.87, 7.12, 5.52, -9.64, 5.58, -9.13, -3.47, -2.26, -1.33, 6.1, -0.86, 9.27, 0.26, 2.8, -7.03, -1.54, 7.17, -1.22, -2.21]
循环内单个结果正确,但最终两个列表值一致,问题出在哪里?
错误原因
Python中列表是可变对象,直接赋值Perf=Range_Days和Perf_mean=Range_Days时,Perf和Perf_mean其实指向同一个列表的内存地址。修改其中一个列表的元素,另一个会同步变化,最终两个列表内容完全相同。
修正方案
方案1:初始化独立空列表
将Perf和Perf_mean初始化为空列表,循环中用append添加计算结果:
Range_Days = list(range(1, 32)) Perf = [] Perf_mean = [] for x in Range_Days: day_data = Ticker_Ch[Ticker_Ch["day"] == x]['% Change'] # 跳过空值(比如第一天的NaN) if not day_data.dropna().empty: total = day_data.sum().round(4) avg = day_data.mean().round(4) else: total = None avg = None Perf.append(total) Perf_mean.append(avg) # 生成目标DataFrame result_df = pd.DataFrame({ '累计值': Perf, '均值': Perf_mean }, index=Range_Days)
方案2:用Pandas分组直接计算(更高效)
不需要手动循环,直接用groupby按day分组,同时计算总和与均值,再重新索引补全1-31日:
# 按day分组计算总和与均值,自动跳过NaN grouped = Ticker_Ch.groupby('day')['% Change'].agg(['sum', 'mean']).round(4) # 重新索引,补全1-31日,缺失值填充为NaN result_df = grouped.reindex(range(1, 32)).rename(columns={'sum': '累计值', 'mean': '均值'})
这个方法更简洁,且利用Pandas内置优化,性能比手动循环更好。
内容的提问来源于stack exchange,提问作者Mario V
相关产品推荐
相关产品推荐

