You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含多日期字段的重复ID数据合并为单行?

按ID合并含重复日期字段的数据解决方案

原始数据(每行含4个日期字段,同一ID的DateIn存在重复):

ID,LName,FName,DateIn,DateOut,Days,ODateIn,ODateOut,Odays
1,Doe,Jay,7/14/2023,8/14/2023,31.00,8/15/2023,4/22/2024,251.00
1,Doe,Jay,3/4/2021,11/5/2021,246.00,11/12/2021,12/31/2021,49.00
1,Doe,Jay,7/14/2023,8/14/2023,31.00,5/30/2024,7/2/2024,33.00
1,Doe,Jay,5/8/2022,1/1/2023,238.00,2/28/2023,4/8/2023,39.00
2,Smith,Dude,4/16/2022,6/2/2022,47.00,7/23/2022,9/13/2022,52.00
2,Smith,Dude,12/5/2022,3/14/2023,99.00,8/30/2023,10/11/2023,42.00
2,Smith,Dude,1/3/2024,3/30/2024,87.00,7/18/2024,9/1/2024,45.00
3,Doe,Jane,4/6/2020,8/10/2020,126.00,11/12/2020,1/18/2021,67.00
3,Doe,Jane,4/6/2020,8/10/2020,126.00,3/27/2021,6/9/2021,74.00
3,Doe,Jane,4/6/2020,8/10/2020,126.00,10/4/2021,11/30/2021,57.00

目标格式(按ID合并为单行,重复DateIn仅保留一组,O日期保留所有记录):

ID,DateIn1,DateOut1,Days1,DateIn2,DateOut2,Days2,DateIn3,DateOut3,Days3,ODateIn1,ODateOut1,Days1,ODateIn2,ODateOut2,Days2,ODateIn3,ODateOut3,Days3,ODateIn4,ODateOut4,Days4
1,3/4/2021,11/5/2021,246.00,5/8/2022,1/1/2023,238.00,7/14/2023,8/14/2023,31.00,11/12/2021,12/31/2021,49.00,2/28/2023,4/8/2023,39.00,8/15/2023,4/22/2024,251.00,5/30/2024,7/2/2024,33.00
2,4/16/2022,6/2/2022,47.00,12/5/2022,3/14/2023,99.00,1/3/2024,3/30/2024,87.00,7/23/2022,9/13/2022,52.00,8/30/2023,10/11/2023,42.00,7/18/2024,9/1/2024,45.00,,,
3,4/6/2020,8/10/2020,126.00,,,,,,,11/12/2020,1/18/2021,67.00,3/27/2021,6/9/2021,74.00,10/4/2021,11/30/2021,57.00,,,

使用pivot方法时,因DateIn存在重复值导致无法正确合并,以下是可行解决方案:


解决方案步骤

1. 数据预处理与分组

将主日期组(DateIn/DateOut/Days)和O日期组(ODateIn/ODateOut/Odays)分开处理,分别转宽表后再合并:

import pandas as pd

# 读取原始数据
df = pd.read_csv("your_data.csv")

# ---------------------- 处理主日期组(去重后转宽表) ----------------------
# 提取主日期相关字段并去重
main_dates = df[["ID", "DateIn", "DateOut", "Days"]].drop_duplicates()
# 按ID分组,给每个唯一的主日期添加序号(从1开始)
main_dates["main_seq"] = main_dates.groupby("ID").cumcount() + 1
# 转宽表:将序号作为后缀添加到字段名
main_wide = main_dates.pivot(
    index="ID",
    columns="main_seq",
    values=["DateIn", "DateOut", "Days"]
).reset_index()
# 重命名列,比如DateIn_1 → DateIn1
main_wide.columns = ["ID"] + [f"{col[0]}{col[1]}" for col in main_wide.columns[1:]]

# ---------------------- 处理O日期组(保留所有记录转宽表) ----------------------
# 提取O日期相关字段
o_dates = df[["ID", "ODateIn", "ODateOut", "Odays"]]
# 按ID分组,给每个O日期记录添加序号(从1开始)
o_dates["o_seq"] = o_dates.groupby("ID").cumcount() + 1
# 转宽表:将序号作为后缀添加到字段名
o_wide = o_dates.pivot(
    index="ID",
    columns="o_seq",
    values=["ODateIn", "ODateOut", "Odays"]
).reset_index()
# 重命名列,将Odays替换为目标格式的Days
o_wide.columns = ["ID"] + [f"{col[0].replace('Odays', 'Days')}{col[1]}" for col in o_wide.columns[1:]]

# ---------------------- 合并两个宽表并调整列顺序 ----------------------
# 按ID合并
final_df = pd.merge(main_wide, o_wide, on="ID", how="left")
# 按目标格式的列顺序排序
target_cols = [
    "ID",
    "DateIn1", "DateOut1", "Days1",
    "DateIn2", "DateOut2", "Days2",
    "DateIn3", "DateOut3", "Days3",
    "ODateIn1", "ODateOut1", "Days1",
    "ODateIn2", "ODateOut2", "Days2",
    "ODateIn3", "ODateOut3", "Days3",
    "ODateIn4", "ODateOut4", "Days4"
]
# 填充缺失列并调整顺序,空值替换为空字符串
final_df = final_df.reindex(columns=target_cols).fillna("")

# 导出结果
final_df.to_csv("result.csv", index=False)

代码说明

  • 主日期组处理:先去重确保每个ID的DateIn仅保留唯一值,通过cumcount生成序号后转宽表,得到带数字后缀的字段。
  • O日期组处理:不做去重,直接给每个ID下的O日期记录生成序号,转宽表时将Odays替换为目标格式的Days后缀。
  • 合并与调整:将两个宽表按ID合并,按目标列顺序调整后填充空值,最终导出符合要求的CSV。

内容的提问来源于stack exchange,提问作者ThatOneGirl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 13:58:11