python - 合并(更新\插入)pandas 数据帧的更好方法

标签 python pandas dataframe merge

我有 2 个 Pandas 数据框 - df_current_data、df_new_data。

我的目标是应用合并(不是 Pandas 合并函数,像“更新\插入”这样的合并)。匹配检查是通过键列进行的。

我的结果需要由 3 个可选的行类型构建。

  • df_current_data 中存在但 df_new_data 中不存在的行 - 将“按原样”插入结果。
  • df_new_data 中存在但 df_current_data 中不存在的行 - 将“按原样”插入结果。
  • 存在于 df_new_data 和 df_current_data 中的行 - 结果需要从 df_new_data 中获取行。

  • 这是一个经典的合并更新插入操作。

    例子:
    # rows 0,1 are in current and not in new (check by index1 and index2)
    # row 2 is common
    In [41]: df_current_source
    Out[41]:    A  index1  index2
             0  1       1       4
             1  2       2       5
             2  3       3       6
    
    # rows 0,2 are in new and not in current (check by index1 and index2)
    # row 1 is common
    In [42]: df_new_source
    Out[42]:    A  index1  index2
             0  4       2       7
             1  5       3       6
             2  6       4       5
    
    # the result has 2 rows that only in current (rows 0,1)
    # the result has 2 rows that only in new (rows 3,4)
    # the result has one row that exists in both current and new (row 2 - index1 = 3, index2 = 6) - so the value of the column A is from the new and not from the current (5 instead of 2)
    
    In [43]: df_result
    Out[43]:    A  index1  index2
             0  1       1       4
             1  2       2       5
             2  5       3       6
             3  4       2       7
             4  6       4       5
    

    这就是我所做的:
    # left join from source to new
    df = df_current_source.merge(df_new_source, how='left', left_on=p_new_keys, 
    right_on=p_curr_keys, indicator=True)
    
    # take only the rows that exists in the current and not exists in the source
    df_only_current = df[df['_merge'] == 'left_only']
    
    # merge new data into current data
    df_result = pd.concat([df_only_current, df_new_source])
    

    另一种选择是使用 isin 功能:
    df_result = pd.concat([df_current_source[~df_current_source[p_key_col_name]\
    
    .isin(df_new_source[p_key_col_name])], df_new_source])
    

    问题是,如果我有 1 个以上的键列,我不能使用 isin,我需要合并。

    假设 current 比 new 大很多,我想最好的方法是直接用 new 的行更新 current 的匹配行,并将“new”数据帧的新行附加到 current 中。

    但我不知道该怎么做..

    非常感谢。

    最佳答案

    选项 1:使用 indicator=True作为 merge 的一部分:

    df_out = df_current_source.merge(df_new_source, 
                                     on=['index1', 'index2'], 
                                     how='outer', indicator=True)
    
    df_out['A'] = np.where(df_out['_merge'] == 'both',
                           df_out['A_y'],
                           df_out.A_x.add(df_out.A_y, fill_value=0)).astype(int)
    
    df_out[['A', 'index1', 'index2']]
    

    输出:
       A  index1  index2
    0  1       1       4
    1  2       2       5
    2  5       3       6
    3  4       2       7
    4  6       4       5
    

    选项 2:使用 combined_firstset_index
    df_new_source.set_index(['index1', 'index2'])\
                 .combine_first(df_current_source.set_index(['index1', 'index2']))\
                 .reset_index()\
                 .astype(int)
    

    输出:
       index1  index2  A
    0       1       4  1
    1       2       5  2
    2       2       7  4
    3       3       6  5
    4       4       5  6
    

    关于python - 合并(更新\插入)pandas 数据帧的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45796018/

    相关文章:

    python - Pandas 与 Numpy 数据帧

    python - 为需要身份验证的网页使用 selenium 进行 Scrapy

    python - 我将如何修复 pygame 的按键事件不执行任何操作?

    python - 将 af 字符串更改为具有值的元组列表

    r - 使用 dplyr::select 排列列而不进行硬编码

    r - 我如何总结一个因素或字符变量?

    python - Boto3 Glue 客户端对象上缺少 list_schemas() 方法

    python - 使用 Python 导入包含文本和数字数据的文件

    python - 检测 Pandas 中缺失的列标签

    基于多列的 Pandas 排名