大熊猫有效地合并和更新

时间:2019-11-12 22:30:06

标签: python pandas dataframe merge

我正在从数据库中获取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个不同的列的组合。 不幸的是,我的解决方案无法正常工作。

3 个答案:

答案 0 :(得分:3)

使用DataFrame.appendDataframe.drop_duplicatesSeries.update

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

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

答案 1 :(得分:3)

Merge数据帧,updateone中包含来自one_的值,然后删除此临时列。

df = df1.merge(df2, on=['idx1', 'idx2'], how='outer', suffixes=['', '_'])
df['one'].update(df['one_'])
>>> df.drop(columns=['one_'])
  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

答案 2 :(得分:1)

一行combine_first

Yourdf=df2.set_index(['idx1','idx2']).combine_first(df1.set_index(['idx1','idx2'])).reset_index()
Yourdf
Out[216]: 
  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