如何在Pandas中向前填充DataFrame的A列NaN直至三列值相等
问题:按条件向前填充DataFrame的A列NaN值
原始数据
原始DataFrame定义如下:
import pandas as pd import numpy as np df = pd.DataFrame({ "A": ["sell", np.nan, np.nan, np.nan, np.nan, "buy", np.nan, np.nan, np.nan, np.nan], "B": ["buy", "buy", "sell", "buy", "buy", np.nan, "buy", "buy", "buy", np.nan], "C": ["sell", "sell", "sell", "sell", "buy", "sell", "sell", "buy", "buy", np.nan] }, index=pd.date_range("2025-05-22", periods=10, freq="15min"))
输出结果:
A B C 2025-05-22 00:00:00 sell buy sell 2025-05-22 00:15:00 NaN buy sell 2025-05-22 00:30:00 NaN sell sell 2025-05-22 00:45:00 NaN buy sell 2025-05-22 01:00:00 NaN buy buy 2025-05-22 01:15:00 buy NaN sell 2025-05-22 01:30:00 NaN buy sell 2025-05-22 01:45:00 NaN buy buy 2025-05-22 02:00:00 NaN buy buy 2025-05-22 02:15:00 NaN NaN buy
需求说明
对A列的NaN值进行向前填充,但填充仅持续到A、B、C三列的值完全相等为止,超出该位置的NaN保持不变。
期望结果
A B C 2025-05-22 00:00:00 sell buy sell 2025-05-22 00:15:00 sell buy sell 2025-05-22 00:30:00 sell sell sell 2025-05-22 00:45:00 NaN buy sell 2025-05-22 01:00:00 NaN buy buy 2025-05-22 01:15:00 buy NaN sell 2025-05-22 01:30:00 buy buy sell 2025-05-22 01:45:00 buy buy buy 2025-05-22 02:00:00 NaN buy buy 2025-05-22 02:15:00 NaN NaN buy
解决方案
核心思路是先完成全量向前填充,再通过条件筛选保留符合要求的填充值,超出三列相等位置的部分恢复为NaN。具体代码如下:
import pandas as pd import numpy as np # 原始DataFrame(重复定义仅为完整演示,实际可省略) df = pd.DataFrame({ "A": ["sell", np.nan, np.nan, np.nan, np.nan, "buy", np.nan, np.nan, np.nan, np.nan], "B": ["buy", "buy", "sell", "buy", "buy", np.nan, "buy", "buy", "buy", np.nan], "C": ["sell", "sell", "sell", "sell", "buy", "sell", "sell", "buy", "buy", np.nan] }, index=pd.date_range("2025-05-22", periods=10, freq="15min")) # 1. 对A列做向前填充,生成临时列 df['A_ffill'] = df['A'].ffill() # 2. 标记三列值完全相等的行(自动排除B/C为NaN的情况,因NaN不与任何值相等) mask_equal = (df['A_ffill'] == df['B']) & (df['A_ffill'] == df['C']) # 3. 按A列非NaN值分组,找到每个分组内第一个三列相等的位置 groups = df['A'].notna().cumsum() first_equal = mask_equal.groupby(groups).idxmax() # 4. 生成最终A列:仅保留从非NaN值到第一个相等行之间的填充值,其余设为NaN df['A'] = np.where(df.index <= first_equal.loc[groups].values, df['A_ffill'], np.nan) # 清理临时列 df.drop('A_ffill', axis=1, inplace=True) # 输出结果 print(df)
代码逻辑说明
- 步骤1:先对A列做全量向前填充,得到所有可能的填充候选值;
- 步骤2:通过布尔掩码标记出A(填充后)、B、C三列值完全一致的行;
- 步骤3:以A列的非NaN值为分组起点,找到每个分组内第一个满足三列相等的行索引;
- 步骤4:通过
np.where判断,仅保留分组内从非NaN值到第一个相等行之间的填充值,其余位置恢复为NaN。
内容的提问来源于stack exchange,提问作者beni
相关产品推荐
相关产品推荐

