基于Pandas按条件匹配更新数据集值的问题求助
问题需求
通过匹配area和Date列生成数据集df3,规则如下:
- 用
df1中的bb、aa、cc值覆盖df2中对应匹配行的同名字段 - 无日期/区域匹配的行,将
bb、aa、cc设为0 - 保留
df2的所有行及stat字段
原始数据
df1数据
Date area bb aa cc 7/1/2023 Australia 30 0 0 8/1/2023 Australia 50 0 0 4/1/2024 Australia 0 0 12 6/1/2024 Australia 30 0 24 9/1/2024 Australia 0 0 24 11/1/2024 Australia 0 0 24 2/1/2025 Australia 35 0 0
df2数据
Date area bb aa cc stat 03/1/2023 Australia 5 5 5 yes 06/1/2023 Australia 0 0 0 no 07/1/2023 Australia 0 0 0 yes 08/1/2023 Australia 0 0 0 yes 09/1/2023 Australia 0 0 0 no 10/1/2023 Australia 0 0 0 no 02/1/2024 Australia 0 0 0 no 03/1/2024 Australia 0 0 0 yes 04/1/2024 Australia 0 0 0 yes 05/1/2024 Australia 0 0 0 no 06/1/2024 Australia 0 0 0 no 9/1/2024 Australia 10 10 10 yes 11/1/2024 Australia 10 11 20 yes 2/1/2025 Australia 35 0 0 yes 1/1/2026 Malaysia 7 9 8 no
期望df3结果
Date area bb aa cc stat 03/1/2023 Australia 0 0 0 yes 06/1/2023 Australia 0 0 0 no 07/1/2023 Australia 30 0 0 yes 08/1/2023 Australia 50 0 0 yes 09/1/2023 Australia 0 0 0 no 10/1/2023 Australia 0 0 0 no 02/1/2024 Australia 0 0 0 no 03/1/2024 Australia 0 0 0 yes 04/1/2024 Australia 0 0 12 yes 05/1/2024 Australia 0 0 0 no 06/1/2024 Australia 30 0 24 no 9/1/2024 Australia 0 0 24 yes 11/1/2024 Australia 0 0 24 yes 2/1/2025 Australia 35 0 0 yes 1/1/2026 Malaysia 0 0 0 no
原代码问题分析
原代码存在以下问题:
- 日期列名称大小写不一致(
Date/date),可能导致匹配失败 - 合并后仅保留非
_y后缀的列,但未正确实现"用df1值覆盖df2"的逻辑,且未处理无匹配行设0的需求 - 列名处理方式可能丢失部分数据,覆盖逻辑不彻底
解决方案代码
import pandas as pd # 统一日期列名并转换为datetime类型(dayfirst=True确保日期格式正确解析) df1 = df1.rename(columns={"Date": "date"}) df2 = df2.rename(columns={"Date": "date"}) df1["date"] = pd.to_datetime(df1["date"], dayfirst=True) df2["date"] = pd.to_datetime(df2["date"], dayfirst=True) # 右连接,保留df2所有行,添加后缀区分来自两个表的字段 merged = pd.merge(df2, df1, on=["area", "date"], how="right", suffixes=("_df2", "_df1")) # 处理bb、aa、cc字段:用df1的值覆盖,无匹配则设为0 for col in ["bb", "aa", "cc"]: merged[col] = merged[f"{col}_df1"].fillna(0).astype(int) # 筛选需要的列并调整顺序 df3 = merged[["date", "area", "bb", "aa", "cc", "stat"]] # 将日期转回原始格式(去除前导0,和示例格式一致) df3["date"] = df3["date"].dt.strftime("%d/%m/%Y").str.lstrip('0') # 输出结果 print(df3)
关键说明
- 日期匹配:统一列名并转换为datetime类型,解决了
7/1/2023和07/1/2023这类格式差异导致的匹配失败问题 - 覆盖逻辑:通过遍历字段,用
df1的对应值填充,空值(无匹配行)设为0,严格实现需求 - 行保留:右连接确保
df2的所有行都被保留,包括无匹配的行
内容的提问来源于stack exchange,提问作者Lynn
相关产品推荐
相关产品推荐

