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

基于PRODUCT_CODE合并Pandas DataFrame行的实现问题

Pandas合并DataFrame:按PRODUCT_CODE合并行且不丢失数据

我正在尝试用Pandas合并两个DataFrame,要求当PRODUCT_CODE列值相同时,合并对应行且不丢失任何数据列的值。以下是我的期望输出、已尝试代码及当前不符合预期的输出,寻求正确实现方法:

期望输出

PRODUCT_CODESERIAL_CODEBATCH_IDTL_CODETL_EXPIRYPCE_STATUSPCE_SN_STATUSPCE_EXPIRY
PC001SC001B001T0012023-10-01NaNNaNNaN
PC002SC002B002T0022023-10-02NaNNaNNaN
PC004SC004B004T0032023-10-03ActiveValidNaN
PC005SC005B005NaNNaNInactiveInvalid2024-10-02
PC006SC006B006NaNNaNActiveValid2024-10-03

已尝试的代码

创建示例DataFrame

import pandas as pd

desired_order = ['PRODUCT_CODE', 'SERIAL_CODE', 'BATCH_ID', 'TL_CODE', 'TL_EXPIRY', 'PCE_STATUS', 'PCE_SN_STATUS', 'PCE_EXPIRY']

df1 = pd.DataFrame({'PRODUCT_CODE': ['PC001', 'PC002', 'PC004'],
                   'SERIAL_CODE': ['SC001', 'SC002', ''],
                   'BATCH_ID': ['B001', 'B002', ''],
                   'TL_CODE': ['T001', 'T002', 'T003'],
                   'TL_EXPIRY': ['2023-10-01', '2023-10-02', '2023-10-03']})

df2 = pd.DataFrame({'PRODUCT_CODE': ['PC004', 'PC005', 'PC006'],
                   'SERIAL_CODE': ['SC004', 'SC005', 'SC006'],
                   'BATCH_ID': ['B004', 'B005', 'B006'],
                   'PCE_STATUS': ['Active', 'Inactive', 'Active'],
                   'PCE_SN_STATUS': ['Valid', 'Invalid', 'Valid'],
                   'PCE_EXPIRY': ['2024-10-01', '2024-10-02', '2024-10-03']})

尝试的合并函数

def combine_and_rearrange_dataframes(df1, df2, desired_order):
    # 拼接DataFrames
    combined_df = pd.concat([df1, df2], ignore_index=True)

    # 提取唯一列
    unique_columns = combined_df.columns.union(df1.columns)

    # 按期望顺序排列列
    final_df = combined_df[desired_order]

    # 根据PRODUCT_CODE更新行
    matching_product_codes = final_df['PRODUCT_CODE'].unique()
    for product_code in matching_product_codes:
        df_subset = final_df[final_df['PRODUCT_CODE'] == product_code]
        df_subset_updated = df1[df1['PRODUCT_CODE'] == product_code]
        final_df.update(df_subset_updated)

    return final_df

result = combine_and_rearrange_dataframes(df1, df2, desired_order)
print(result)

当前不符合预期的输出

PRODUCT_CODESERIAL_CODEBATCH_IDTL_CODETL_EXPIRYPCE_STATUSPCE_SN_STATUSPCE_EXPIRY
PC001SC001B001T0012023-10-01NaNNaNNaN
PC002SC002B002T0022023-10-02NaNNaNNaN
PC004T0032023-10-03NaNNaNNaN
PC004SC004B004NaNNaNActiveValid
PC005SC005B005NaNNaNInactiveInvalid2024-10-02
PC006SC006B006NaNNaNActiveValid2024-10-03

正确实现方法

之前的concat会生成重复行,update操作还错误覆盖了df2的有效数据。正确做法是使用外连接合并,配合空值处理实现行合并:

完整代码

import pandas as pd

desired_order = ['PRODUCT_CODE', 'SERIAL_CODE', 'BATCH_ID', 'TL_CODE', 'TL_EXPIRY', 'PCE_STATUS', 'PCE_SN_STATUS', 'PCE_EXPIRY']

df1 = pd.DataFrame({'PRODUCT_CODE': ['PC001', 'PC002', 'PC004'],
                   'SERIAL_CODE': ['SC001', 'SC002', ''],
                   'BATCH_ID': ['B001', 'B002', ''],
                   'TL_CODE': ['T001', 'T002', 'T003'],
                   'TL_EXPIRY': ['2023-10-01', '2023-10-02', '2023-10-03']})

df2 = pd.DataFrame({'PRODUCT_CODE': ['PC004', 'PC005', 'PC006'],
                   'SERIAL_CODE': ['SC004', 'SC005', 'SC006'],
                   'BATCH_ID': ['B004', 'B005', 'B006'],
                   'PCE_STATUS': ['Active', 'Inactive', 'Active'],
                   'PCE_SN_STATUS': ['Valid', 'Invalid', 'Valid'],
                   'PCE_EXPIRY': ['2024-10-01', '2024-10-02', '2024-10-03']})

def combine_and_rearrange_dataframes(df1, df2, desired_order):
    # 将df1中的空字符串替换为NaN,方便后续合并时优先取非空值
    df1_clean = df1.replace('', pd.NA)
    
    # 按PRODUCT_CODE做外连接,保留所有行
    merged_df = pd.merge(df1_clean, df2, on='PRODUCT_CODE', how='outer', suffixes=('_df1', '_df2'))
    
    # 合并重复列:优先取df2的值,无值时用df1的值
    merged_df['SERIAL_CODE'] = merged_df['SERIAL_CODE_df2'].combine_first(merged_df['SERIAL_CODE_df1'])
    merged_df['BATCH_ID'] = merged_df['BATCH_ID_df2'].combine_first(merged_df['BATCH_ID_df1'])
    
    # 删除带后缀的冗余列
    cols_to_drop = [col for col in merged_df.columns if '_df1' in col or '_df2' in col]
    merged_df = merged_df.drop(cols_to_drop, axis=1)
    
    # 按期望顺序排列列
    final_df = merged_df[desired_order]
    
    return final_df

# 执行并输出结果
result = combine_and_rearrange_dataframes(df1, df2, desired_order)
print(result)

关键步骤说明

  1. 清理空字符串:把df1中的空字符串替换为pd.NA,确保合并时能正确识别缺失值,优先使用df2的有效值。
  2. 外连接合并:pd.merge(how='outer')保留两个DataFrame中所有PRODUCT_CODE的行,不会丢失任何数据。
  3. 合并重复列:通过combine_first方法,对重复列优先取df2的值,实现同PRODUCT_CODE行的字段合并。
  4. 列重排:最后按指定顺序整理结果列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:45:02