首页 > 解决方案 > pandas 高效合并和更新

问题描述

我正在从数据库中获取 df1。df2 需要与 df1 合并。Df1 包含 df2 中不存在的其他列。df2 包含 df1 中已经存在的索引以及需要更新哪些行。数据框是多索引的。

我想要什么: - 保留 df1 中不在 df2 中的行 - 使用 df2 的值更新 df1 的值以匹配索引 - 在更新的行中保留 df2 中不存在的列的值。-追加在 df2 但不在 df1 中的行

我的解决方案:

import pandas as pd
import numpy as np

df1 = pd.DataFrame(
    data={'idx1': ['A', 'B', 'C', 'D', 'E'], 'idx2': [1, 2, 3, 4, 5], 'one': ['df1', 'df1', 'df1', 'df1', 'df1'],
          'two': ["y", "x", "y", "x", "y"]})

df2 = pd.DataFrame(data={'idx1': ['D', 'E', 'F', 'G'], 'idx2': [4, 5, 6, 7], 'one': ['df2', 'df2', 'df2', 'df2']})

desired_result = pd.DataFrame(data={'idx1': ['A', 'B', 'C', 'D', 'E', 'F', 'G'], 'idx2': [1, 2, 3, 4, 5, 6, 7],
                            'one': ['df1','df1','df1','df2', 'df2', 'df2', 'df2'], 'two': ["y", "x", "y", "x", "y",np.nan,np.nan]})



updated = pd.merge(df1[['idx1', 'idx2']], df2, on=['idx1', 'idx2'], how='right')
keep = df1[~df1.isin(df2)].dropna()
my_res = pd.concat([updated, keep])
my_res.drop(columns='two', inplace=True)

my_res = pd.merge(my_res,df1[['idx1','idx2','two']], on=['idx1','idx2'])

这是非常低效的,因为我:

  1. 通过右外连接 df2 合并到 df1 的仅索引列

  2. 查找在 df2 但不在 df1 中的索引

  3. 连接两个数据框

  4. 删除未包含在 df2 中的列

  5. 合并索引以附加我之前删除的那些列

有没有更有效更简单的方法来做到这一点?我只是无法解决这个问题。

编辑:通过 mutliindexed 我的意思是要识别一行我需要查看 4 个不同的列组合。不幸的是,我的解决方案无法正常工作。

标签: pythonpandasdataframemerge

解决方案


使用DataFrame.append,Dataframe.drop_duplicatesSeries.update:

首先我们附加 df1 和 df2。然后我们根据列idx1和删除重复项idx2。最后,我们根据 df1 中的现有值更新该two列。NaN

df3 = (df1.append(df2, sort=False)
          .drop_duplicates(subset=['idx1', 'idx2'], keep='last')
          .reset_index(drop=True))

df3['two'].update(df1['two'])
  idx1  idx2  one  two
0    A     1  df1    y
1    B     2  df1    x
2    C     3  df1    y
3    D     4  df2    x
4    E     5  df2    y
5    F     6  df2  NaN
6    G     7  df2  NaN

推荐阅读