如何在Pandas中计算滑动4行c1和并除以c2生成c3列?
解决连续4季度c1求和除以c2生成c3列的问题
需求回顾
- 针对时间序列数据(超1万行),计算每行对应连续4行c1的和,再除以当前行的c2值,结果存入新列c3
- 若当前行之后剩余行数不足4行,c3填0
高效解决方案(避免循环)
直接使用pandas的向量化操作,比循环效率高数十倍,适合大数据量:
import pandas as pd # 1. 构建示例数据(用户提供) df = pd.DataFrame({'c1':[20,15,10,12,15,17,19,20,9,10],'c2':[22,14,19,13,15,17,19,10,20,12]}) date_array=[[2019,12,31],[2019,9,30],[2019,6,30],[2019,3,31],[2018,12,31],[2018,9,30],[2018,6,30],[2018,3,31],[2017,12,31],[2017,9,30]] date_df = pd.DataFrame(date_array, columns=['year', 'month', 'day']) df['date'] = pd.to_datetime(date_df[['year', 'month', 'day']], format='%Y-%m-%d') df = df[['date','c1','c2']] # 2. 计算连续4行c1的和 # rolling(4).sum() 计算从当前行往前4行的和,shift(-3) 将结果向前偏移3位,得到当前行开始的连续4行和 c1_rolling_sum = df['c1'].rolling(window=4).sum().shift(-3) # 3. 处理不足4行的情况:将NaN替换为0 c1_rolling_sum = c1_rolling_sum.fillna(0) # 4. 计算c3并保留两位小数 df['c3'] = (c1_rolling_sum / df['c2']).round(2) # 查看结果 print(df)
运行结果
date c1 c2 c3 0 2019-12-31 20 22 2.59 1 2019-09-30 15 14 3.71 2 2019-06-30 10 19 2.84 3 2019-03-31 12 13 4.85 4 2018-12-31 15 15 4.73 5 2018-09-30 17 17 3.82 6 2018-06-30 19 19 3.05 7 2018-03-31 20 10 0.00 8 2017-12-31 9 20 0.00 9 2017-09-30 10 12 0.00
原循环方案的问题
- 索引越界:当
i接近数据末尾时(如i=7),i+3=10超出DataFrame的最大索引(9),导致取数不全,求和错误 - 效率低下:循环遍历1万行数据,速度远低于pandas的向量化操作,且代码冗余
内容的提问来源于stack exchange,提问作者DNS
相关产品推荐
相关产品推荐

