如何基于DataFrame当前行与下一行值添加指定计算列?
解决方案
可以通过**移位(shift)**获取下一行的数据,结合apply调用第三方函数,最后处理最后一行的填充需求,无需手动循环,效率更高。
完整实现代码
import pandas as pd # 示例DataFrame df = pd.DataFrame([[5,6],[1,2],[3,6],[4,1]],columns=['a','b']) # 第三方函数(不可修改) def process(a,b,c,d): return {"notthisone":2*a, "thisone":(a*b+c*d), } # 生成下一行的a、b列 df['a_next'] = df['a'].shift(-1) df['b_next'] = df['b'].shift(-1) # 对前n-1行调用process函数,提取'thisone'值 df['result'] = df.apply( lambda row: process(row['a'], row['b'], row['a_next'], row['b_next'])['thisone'] if pd.notna(row['a_next']) else None, # 最后一行先设为None axis=1 ) # 最后一行复用前一行的result值 df['result'].fillna(method='ffill', inplace=True) # 移除临时的移位列(可选) df.drop(['a_next', 'b_next'], axis=1, inplace=True) print(df)
输出结果
a b result 0 5 6 32.0 1 1 2 20.0 2 3 6 22.0 3 4 1 22.0
关键步骤说明
- 移位获取下一行数据:用
shift(-1)将a、b列整体向上移动一位,得到每一行对应的下一行数据,最后一行的移位列会是NaN。 - 调用第三方函数:通过
apply遍历每一行,仅当移位列不为空时调用process函数,提取目标值;最后一行先标记为None。 - 填充最后一行:用
ffill(向前填充)将最后一行的result设置为前一行的值,满足需求。 - 清理临时列:如果不需要移位后的临时列,可以用
drop移除。
效率优化提示
如果DataFrame数据量极大,apply的效率可能不足,可以改用numpy.vectorize包装第三方函数,配合移位后的数组批量调用:
import numpy as np # 用vectorize包装函数 vec_process = np.vectorize(lambda a,b,c,d: process(a,b,c,d)['thisone']) # 处理前n-1行 result_values = vec_process(df['a'][:-1], df['b'][:-1], df['a'][1:], df['b'][1:]) # 拼接最后一行的值 result_values = np.append(result_values, result_values[-1]) # 赋值给df df['result'] = result_values
这种方式比apply更快,适合大规模数据场景。
内容的提问来源于stack exchange,提问作者KansaiRobot
相关产品推荐
相关产品推荐

