基于两列条件对多列Non-NA值执行向前填充的实现方法
解决方案:分组内针对特定标记行的向前填充
当然有可行的方案啦!结合Python的pandas库就能轻松实现这个需求,我给你一步步拆解说明:
核心思路
我们需要按Name列分组,在每个分组内:
- 筛选出
Flag标记为C或A的行 - 仅对这些行的指定列(非NA值)执行向前填充(ffill)
- 其他标记行的数值保持原样
代码实现(附示例数据)
首先构造一个模拟数据集,方便你理解效果:
import pandas as pd import numpy as np # 构造示例数据 df = pd.DataFrame({ 'Name': ['Alice', 'Alice', 'Alice', 'Bob', 'Bob', 'Bob', 'Bob'], 'Flag': ['A', 'B', 'C', 'C', 'B', 'A', 'B'], 'Col1': [1, np.nan, np.nan, 5, np.nan, np.nan, np.nan], 'Col2': [np.nan, 2, np.nan, np.nan, 6, np.nan, np.nan], 'Col3': [3, np.nan, np.nan, 7, np.nan, np.nan, 8] })
方法一:自定义分组函数(直观易懂)
通过groupby结合自定义函数,精准控制填充范围:
def fill_target_rows(group): # 指定需要执行填充的列 fill_columns = ['Col1', 'Col2', 'Col3'] # 生成掩码:筛选Flag为A或C的行 target_mask = group['Flag'].isin(['A', 'C']) # 仅对掩码选中的行执行向前填充,赋值回原分组 group.loc[target_mask, fill_columns] = group.loc[target_mask, fill_columns].ffill() return group # 按Name分组应用函数,group_keys=False避免额外生成分组索引 result_df = df.groupby('Name', group_keys=False).apply(fill_target_rows)
方法二:transform结合combine_first(更简洁)
利用transform批量处理分组,再合并原数据保留非目标行的值:
fill_columns = ['Col1', 'Col2', 'Col3'] result_df = df.copy() # 对每个分组的目标列,先将非A/C行设为NaN,再执行ffill,最后合并原数据 result_df[fill_columns] = df.groupby('Name')[fill_columns].transform( lambda x: x.where(df['Flag'].isin(['A', 'C']), np.nan).ffill() ).combine_first(df[fill_columns])
效果验证
运行代码后,你会看到:
- Alice组中,
Flag=C的行继承了Flag=A行的Col1=1和Col3=3,而Flag=B行的数值保持不变 - Bob组中,
Flag=A的行继承了Flag=C行的Col1=5和Col3=7,Flag=B行的NaN依然保留
这样就完美实现了你要的「仅在分组内针对特定标记行执行向前填充」的需求!
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

