如何使用Python熊猫加入DataFrame而不重复列,并保持默认值从左到右还是从NaN到左边?

时间:2018-07-16 12:35:58

标签: python pandas dataframe join

我想在索引上合并两个DataFrame(因此join())。
但是两个DataFrame大约有20列,完全一样。 而且,我想避免重复的列,因为要决定保留哪个列,删除一半并重命名其他列可能很麻烦。

我的目标是制作一个DataFrame(我称它为“旧”)作为所有以前DataFrame的历史。因此,我正在构建一个新的数据框,然后将其合并到旧的自身中,等等。随着迭代的进行,旧的DataFrame将随着时间的推移而增加。

这是一个简化的示例

import pandas as pd
df = pd.DataFrame({'A': [1,2,3],
              'B': [4,5,6],
              'C':[7,8,9]}
     ).set_index([[11,22,33]])

old = df.head(2)
new = df.tail(2)

print( old.join(new,how='outer', lsuffix='_left') )

哪个给:

    A_left  B_left  C_left    A    B    C
11     1.0     4.0     7.0  NaN  NaN  NaN
22     2.0     5.0     8.0  2.0  5.0  8.0
33     NaN     NaN     NaN  3.0  6.0  9.0
  • 11 :我知道,如果ID不存在于新的ID中,则应保留该ID,而不要使用NaN创建重复的变量。

  • 22 :如果两个ID都存在,则旧值应被覆盖;丢弃_left列,保留_right。

  • 33 :如果ID在旧版本中不存在,而在新版本中,则只需追加

我已经在文档中搜索了很多,但是找不到任何东西。

到目前为止,我最好的主意是使用后缀进行连接,然后应用过滤器:如果cols A_left,B_left C_left是NaN,则复制A,B,C中的值。删除cols A_left,B_left C_left等。
这似乎不是一个有效的解决方案。

或者可以将它们附加到sort_values上,然后删除重复的ID?

由于我是Python新手,所以这可能不是最好的方法。

2 个答案:

答案 0 :(得分:3)

------------------注释后编辑-------------------------- -----

第一个选项,完整代码: 它会同时保留两个索引,同时使用new的值更新具有相同索引但值不同的行。

import pandas as pd
old = pd.DataFrame({'A': [2,3,4],
              'B': [5,6,4],
              'C':[8,9,4]}
     ).set_index([[22,33,44]])

new = pd.DataFrame({'A': [1,2,3],
              'B': [44,55,66],
              'C':[7,8,9]}
     ).set_index([[11,22,33]])

new
    A   B   C
11  1   44  7
22  2   55  8
33  3   66  9

old
    A   B   C
22  2   5   8
33  3   6   9
44  4   4   4

pd.merge(new, old, on=['A','B','C'], how='outer', right_index=True, left_index=True)

output:
    A   B   C
11  1   44  7
22  2   55  8
33  3   66  9
44  4   4   4

您是否尝试过合并?

    pd.merge(old, new, on=['A','B','C'], how='outer', left_index=True, right_index=True))

Output:

        A   B   C
    11  1   4   7
    22  2   5   8
    33  3   6   9

选项2: 使用追加和删除重复项:

new.append(old).drop_duplicates()

答案 1 :(得分:0)

您可以尝试一下,我认为它将为您服务!

import pandas as pd

df = pd.DataFrame({'A': [1,2,3,4],
              'B': [4,5,6,7],
              'C':[7,8,9,10],
              'D':[10,11,12,14]}
     ).set_index([[11,22,33,44]])

df2 = pd.DataFrame({'A': [1,2,3,4],
              'B': [4,5,6,8],
              'C':[11,12,13,15],
              'D':[14,15,16,17]}
     ).set_index([[11,22,33,44]])
old = df.head(3)
new = df2.tail(3)

intersection = list(set(list(new.index)).intersection(list(old.index)))
old.loc[intersection] = new.loc[intersection]
only_new = [x for x in list(new.index) if x not in list(old.index)]

old.loc[only_new] = new.loc[only_new]