如何在 Python 中按 ID 列合并多行数据为单行(填充非空值)

3次阅读

如何在 Python 中按 ID 列合并多行数据为单行(填充非空值)

本文介绍如何使用 pandas 对具有相同主键(如 P ID)的重复行进行智能合并,通过前向/后向填充保留每列首个有效值,最终将 3130 行去重压缩为约 900 行结构完整的单行记录。

本文介绍如何使用 pandas 对具有相同主键(如 P ID)的重复行进行智能合并,通过前向/后向填充保留每列首个有效值,最终将 3130 行去重压缩为约 900 行结构完整的单行记录。

在数据清洗与报表生成中,常遇到“逻辑重复但信息互补”的情况:多行共享相同主键(如 P ID、T ID、C ID),但各字段(如 Q1、Q2、Q3)的非空值分散在不同行。直接使用 drop_duplicates() 会丢失信息,而简单取 ‘first’ 或 ‘last’ 又存在不确定性——你真正需要的是按组聚合时,对每个字段取其首个非空值(即“拼合”各行的有效信息)

✅ 推荐方案:bfill() + head(1)(推荐用于本场景)

该方法利用“向后填充(back-fill)”将每组内后续行的非空值向上补全至首行,再取首行,从而安全提取每列的首个有效值:

import pandas as pd  # 示例数据(模拟原始 excel 导入结果) df = pd.DataFrame({     "P ID": [318, 318, 319, 319],     "T ID": [495, 495, 496, 496],     "C ID": ["00036282", "00036282", "00036283", "00036283"],     "Q1": ["NO", None, "Yes", None],     "Q2": [None, "Yes", None, "Yes"],     "Q3": [None, "All cost covered", "No additional costs", None], })  # 核心操作:按 P ID 分组 → 每组内向后填充 → 取填充后首行 merged_df = (df.groupby("P ID", sort=False)                .apply(lambda x: x.bfill().head(1))                .reset_index(drop=True))  print(merged_df)

输出:

立即学习Python免费学习笔记(深入)”;

P ID  T ID      C ID    Q1    Q2                   Q3 0   318   495  00036282    NO   Yes  All cost covered 1   319   496  00036283   Yes   Yes  No additional costs

优势:不依赖字段类型(字符串/数值/空值兼容)、语义清晰(取“最早出现的有效回答”)、结果确定且可复现。

? 替代方案:first() 配合 fillna()(适用于需自定义填充逻辑)

若需更精细控制(例如仅对特定列启用填充),可先用 fillna(method=’bfill’) 预处理,再调用 first():

merged_df_alt = (df.groupby("P ID", sort=False)                   .apply(lambda x: x.fillna(method='bfill').iloc[0])                   .reset_index(drop=True))

或逐列指定聚合方式(更显式,适合混合类型字段):

agg_funcs = {col: 'first' for col in df.columns if col != "P ID"} # 注意:'first' 在 pandas 中会自动跳过 NaN,等效于取首个非空值 merged_df_explicit = df.groupby("P ID", sort=False).agg(agg_funcs).reset_index()

⚠️ 重要注意事项

  • sort=False 参数建议显式添加,避免因默认排序打乱原始组内顺序,影响 bfill/first 的行为;
  • 若存在多组完全空值(如某 Q3 列全为 NaN),first() 和 bfill().head(1) 均会返回 NaN,符合预期;
  • 确保分组键(如 “P ID”)拼写与原始 DataFrame 列名严格一致(注意大小写与空格);
  • 处理前建议执行 df.isnull().sum() 检查空值分布,验证策略合理性;
  • 最终导出 Excel 时,使用 merged_df.to_excel(“cleaned_output.xlsx”, index=False) 即可获得目标格式。

通过上述方法,你不仅能将 3130 行原始数据精准压缩为约 900 行无损合并结果,还可确保所有字段(包括 T ID、C ID 等辅助键)保持一致性——真正实现自动化、可验证、可复现的数据整合。

text=ZqhQzanResources