使用loc函数时Pandas DataFrame未实现递归更新,求解决方法
问题:实现基于触发列与前序状态的DataFrame列递归更新
初始数据
import pandas as pd import numpy as np df_strat = pd.DataFrame({'in_pos': [0, 0, 0, 1, 0, 0, -1, 0, 0, 0], 'in': [0, 0, 0, 1, 0, 0, -1, 0, 0, 0]})
需求
更新in列,规则如下:
- 当
in_pos列出现非0值(如1/-1)时,当前行in设为该值 - 当
in列的上一行值为非0值时,当前行in继承该值 - 规则需支持任意非0值集
预期结果
df_expected = pd.DataFrame({'in_pos': [0, 0, 0, 1, 0, 0, -1,0,0,0], 'in': [0, 0, 0, 1, 1, 1, -1, -1, -1,-1]})
无效尝试
- loc单值更新:仅能更新单行,无法实现状态的递归传递
df_strat.loc[(df_strat['in_pos'].shift(1) == 1) | (df_strat['in'].shift(1) == 1), 'in'] = 1
- np.select方法:仅基于原始数据判断,无法利用更新后的行值,不符合递归逻辑
conditions = [ (df_strat['in_pos'] == 1) | (df_strat['in'].shift(1).fillna(0) == 1), (df_strat['in_pos'] == -1) | (df_strat['in'].shift(1).fillna(0) == -1), (df_strat['in_pos'] == 0) | (df_strat['in'].shift(1).fillna(0) == 0)] df_strat['in'] = np.select(conditions, [1, -1, 0], default=df_strat['in'])
解决方案
利用ffill()(向前填充)实现状态传递,核心逻辑是先提取in_pos中的触发值,再将该值向后传递:
简洁实现
# 提取in_pos的非0触发值,替换0为NaN后向前填充,最后补全初始0值 df_strat['in'] = df_strat['in_pos'].replace(0, np.nan).ffill().fillna(0)
分步解释
- 提取触发值:将
in_pos中的0替换为NaN,保留非0的触发信号 - 向前填充:用前一个非NaN值填充当前行,实现状态传递
- 补全初始值:将开头未被填充的
NaN替换为0
验证结果
执行后df_strat的in列与预期完全一致。
内容的提问来源于stack exchange,提问作者gfx Prog
相关产品推荐
相关产品推荐

