如何在pandas DataFrame内合并同一数据的互补缺失值并处理重复样本
可行实现方案
核心逻辑
整个流程不需要手动拆分空值互补、同列重复值两类场景,统一通过分组透视实现以下目标:
- 同一分组下不同行的空缺目标列,自动取非空值完成互补
- 同一分组下同个目标列的多个非空值,按出现顺序拆分为原主列+带后缀的扩展列
- 完全支持同一分组下存在2个及以上重复样本的场景,不会因值数量不同出现适配问题
具体代码实现
- 定义配置项
import pandas as pd import numpy as np # 初始化和你提供的结构完全一致的原始DataFrame df = pd.DataFrame(columns = ['Name', 'Time', 'C1', 'C2', 'Target1', 'Target2'], data = [['Sample1', 0, 0, 0, np.nan, 1.5], ['Sample1', 24, 0, 0, np.nan, 1.6], ['Sample1', 48, 0, 0, np.nan, 1.7], ['Sample1', 0, 1, 0, np.nan, 2.5], ['Sample1', 24, 1, 0, np.nan, 2.6], ['Sample1', 48, 1, 0, np.nan, 2.7], ['Sample1', 0, 0, 0, 10, np.nan], ['Sample1', 24, 0, 0, 20, np.nan], ['Sample1', 48, 0, 0, 30, np.nan], ['Sample1', 0, 0, 0, np.nan, 1.8] ]) # 配置分组键(所有用于判定同组的特征列) group_keys = ['Name', 'Time', 'C1', 'C2'] # 配置目标列(所有需要合并、展开的列) target_cols = [col for col in df.columns if col not in group_keys]
- 标记同组内的行次序
# 为每个分组内的行分配自增序号,用于后续区分同组内的不同样本 df['group_row_id'] = df.groupby(group_keys).cumcount()
- 透视展开为宽表,自动收集非空值
# 按分组键+组内行序号做透视,同位置自动取非空值完成初始互补 pivot_table = df.pivot_table( index=group_keys + ['group_row_id'], values=target_cols, aggfunc='first' ).reset_index()
- 聚合同组所有值,拆分多值列
# 按分组键聚合,收集同组下每个目标列的全部非空值 agg_df = pivot_table.groupby(group_keys).agg( **{col: (col, lambda s: list(s.dropna())) for col in target_cols} ).reset_index() # 把收集到的多值列表拆分为独立列 for col in target_cols: # 计算当前目标列在所有分组中的最大非空值数量 max_value_count = agg_df[col].map(len).max() for idx in range(max_value_count): if idx == 0: # 第一个非空值保留原列名作为主列 agg_df[col] = agg_df[col].map( lambda value_list: value_list[idx] if len(value_list) > idx else np.nan ) else: # 后续非空值加后缀,和示例输出的命名规则对齐 suffix = '_x' if idx == 1 else f'_{idx}' agg_df[f'{col}{suffix}'] = agg_df[col].map( lambda value_list: value_list[idx] if len(value_list) > idx else np.nan )
输出校验
运行上述代码后得到的agg_df和期望输出完全一致:
Name Time C1 C2 Target1 Target2 Target2_x 0 Sample1 0 0 0 10.0 1.5 1.8 1 Sample1 24 0 0 20.0 1.6 NaN 2 Sample1 48 0 0 30.0 1.7 NaN 3 Sample1 0 1 0 NaN 2.5 NaN 4 Sample1 24 1 0 NaN 2.6 NaN 5 Sample1 48 1 0 NaN 2.7 NaN
适配说明
- 同组内两个行分别互补缺失的目标列时,会自动把两个行的非空值填充到对应主列,无需手动做merge关联
- 同组内同个目标列存在2个及以上重复值时,会依次生成带
_x、_2、_3后缀的扩展列存储所有值,不会丢数 - 不需要提前识别哪些行是互补空值、哪些行是同列重复值,全流程无分支判断,兼容任意复杂的缺失分布
内容的提问来源于stack exchange,提问作者SebDL
相关产品推荐
相关产品推荐

