Python中如何每次迭代2行pandas数据并新增列存储相邻两行计算结果?
问题解决方法
原代码存在的问题
- 用
iterrows()返回的行对象row1/row2作为loc的索引参数,属于语法错误,应该用返回的第一个值idx1/idx2作为行索引定位 - 循环内反复给全量列
new_column赋值,会导致值被覆盖,逻辑不符合需求 - 额外创建两个冗余中间列,没有必要
修改后的逐行迭代版本(匹配你原有实现思路)
from itertools import tee from itertools import zip_longest as izip import pandas as pd # 先初始化new_column列为空值 df['new_column'] = pd.NA def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return izip(a, b) for (idx1, row1), (idx2, row2) in pairwise(df.iterrows()): # 计算前一日待办和当日待办 backlog_yesterday = row1['column2'] - row1['column4'] backlog_today = row2['column2'] - row2['column4'] # 只给每组的第二行赋值总和 df.loc[idx2, 'new_column'] = backlog_yesterday + backlog_today
更优的向量化实现(性能更高,不需要循环)
pandas内置的shift方法可以直接偏移行获取前一行的值,几行代码即可实现需求:
# 先计算每行的待办值 df['backlog'] = df['column2'] - df['column4'] # 第二行及以后的新列值 = 当前待办 + 前一行待办 df['new_column'] = df['backlog'] + df['backlog'].shift(1) # 如果不需要保留中间backlog列可以删掉 df.drop('backlog', axis=1, inplace=True)
最终输出结果验证
| Date | column1 | column2 | column3 | column4 | new_column |
|---|---|---|---|---|---|
| 2021-08-20 | 19 | 30 | 11 | 8 | |
| 2021-08-21 | 15 | 25 | 11 | 4 | 43 |
| 2021-08-22 | 5 | 10 | 5 | 0 | 31 |
| 2021-08-23 | 25 | 36 | 16 | 9 | 37 |
| 2021-08-24 | 6 | 6 | 6 | 0 | 33 |
内容的提问来源于stack exchange,提问作者RCN
相关产品推荐
相关产品推荐

