如何在Pandas DataFrame中新增列并使用shift函数实现累计求和?
问题解答
你最初的方案出错的核心原因是:pandas默认执行向量化运算,你运行df["B"]=df["A"] + df["B"].shift(1)时,等号右侧的df["B"].shift(1)是基于你刚赋值为全0的B列一次性计算得到的,不会每计算完一行B就动态更新再计算下一行,所以只会做一次向量加法,无法得到逐层累加的结果。
用shift实现累计求和的方案
可以用shift函数实现累计求和,但不能用你原来的一次性向量化写法,需要配合逐行迭代,保证每一行计算时,上一行的B值已经是累加后的结果,示例代码如下:
import pandas as pd data = {'Counter':list(range(1, 10)), 'Country':['USA','UK','UK','USA','UK','USA','UK','USA','UK'], 'A':[0,0,1,1,1,1,1,1,1] } df=pd.DataFrame(data) df["B"] = 0 # 逐行迭代计算累计值 for i in range(1, len(df)): df.loc[i, "B"] = df.loc[i, "A"] + df["B"].shift(1).loc[i] # 第一行没有上一行数据,直接赋值为A列第一行的值 df.loc[0, "B"] = df.loc[0, "A"] print(df)
运行后得到的正确累计求和结果如下:
Counter Country A B 0 1 USA 0 0 1 2 UK 0 0 2 3 UK 1 1 3 4 USA 1 2 4 5 UK 1 3 5 6 USA 1 4 6 7 UK 1 5 7 8 USA 1 6 8 9 UK 1 7
注意事项
- 上述用
shift配合迭代的写法仅适合学习原理使用,实际业务场景中直接使用pandas原生的cumsum方法即可,代码更简洁,性能也高得多:df["B"] = df["A"].cumsum() - 迭代写法在数据量较大的时候会比原生向量化的
cumsum慢几个数量级,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Naor
相关产品推荐
相关产品推荐

