基于另一列条件的Pandas ffill实现问题求助
问题:按指定规则前向填充check1列的True值
首先给出DataFrame片段:
import pandas as pd df = pd.DataFrame({ 'sig_2':[False, False, True, True, True, True, True, True, True, True, True, False, False, False, False, True, False, True, True, True, True, True, True, True, True, True, False, False, False, False, True, True, True, True, False, True, True], 'tr_cnt':[0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 1, 2, 3, 4, 0, 1, 2], 'fls_cnt':[53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 1, 0, 0], 'test1':[0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 1, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 4, 4, 4, 4, 0, 16, 16], 'test2':[54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 1, 0, 0], 'check1':[False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False]})
列含义说明
tr_cnt:sig_2列中连续True行的计数fls_cnt:连续False行的计数test1/test2:连续行的总计数check1:满足(df['test1'] > 2) & (df['fls_cnt'].shift(1) >= 2)条件的行标记为True
需求
将check1列中的True值,按照其对应的test1列值进行前向填充:
- 第一个True行对应
test1=9,需向前填充8行(即该行及后续8行都标记为True) - 第二个True行对应
test1=4,需向前填充3行(该行及后续3行都标记为True)
尝试过的方法(均存在问题)
mask = (df['test1'] > 2) & (df['fls_cnt'].shift(1) >= 2) # Trial 1 groups = mask.ne(mask.shift()).cumsum() df['test1'] = df.groupby(groups)['test1'].ffill().astype(bool) # Trial 2 df['test2'] = df.groupby(mask)['test1'].ffill().astype(bool) # Trial 3 groups = (~mask).cumsum() df['test3'] = df.groupby(groups)['test1'].ffill().astype(bool) # Trial 4 df["test4"] = df.groupby(mask.cumsum())['test1'].ffill().fillna(False).astype(bool)
上述方法的问题:虽然在满足条件的行上实现了部分效果,但错误地将不符合条件的行也标记为True。
正确实现方案
核心思路:定位所有check1为True的行,为每个目标行标记其自身及后续test1-1行为True,最后合并所有标记结果。
# 初始化结果列为原check1的拷贝 df['result'] = df['check1'].copy() # 获取所有check1为True的行索引 true_indices = df[df['check1']].index for idx in true_indices: # 计算需要填充的行数:test1值减1 fill_rows = df.loc[idx, 'test1'] - 1 # 确定填充的结束索引,避免超出DataFrame范围 end_idx = min(idx + fill_rows, df.index.max()) # 标记目标区间的行为True df.loc[idx:end_idx, 'result'] = True
验证结果:
- 索引2的行(第一个True):填充范围为2~10,对应行全部标记为True
- 索引30的行(第二个True):填充范围为30~33,对应行全部标记为True
其余行保持原check1的False值,完全符合需求。
内容的提问来源于stack exchange,提问作者Michael Felman
相关产品推荐
相关产品推荐

