pandas通过逐列的另一个数据帧更新数据帧

时间:2016-10-07 03:30:40

标签: python pandas

我有两个像这样的数据框

      A  B   C   D  E
   0  1  1   c  d1  A
   1  2  1  A1  B1  A
   2  3  1  A2  B2  S
   3  4  1  c3  d3  S
   4  5  1  A4  B4  S

我想用df2更新df1的C,D列,当它们在A中得到相同的列值时(如果df1 ['A'] == df2 ['A']则df1 ['C'] = df2 [' C']和df1 ['D'] = df2 ['D'])

答案应该是这样的

df1.update(df2)

我尝试了>df1.update(df2) > A B C D E 0 1 1 c d1 A 1 6 1 c1 d1 A 2 9 1 c2 d2 S 3 4 1 c3 d3 S 4 5 1 A4 B4 S ,但它只是用df2

覆盖了df1
pd.merge(df1, df2,how='inner' ,on=['A'])

我尝试 A B C_x D_x E C_y D_y 0 1 1 A B0 A c d1 1 4 1 A3 B3 S c3 d3 仍然不是我想要的

{{1}}

任何人都可以给我一些建议吗? 谢谢

1 个答案:

答案 0 :(得分:2)

我认为这会更节省空间:

编辑添加

这可能更有效:

In [22]: df1,df2 = df1.align(df2,join='left',axis=0)

In [23]: df1
Out[23]: 
   A  B   C   D  E
0  1  1   A  B0  A
1  2  1  A1  B1  A
2  3  1  A2  B2  S
3  4  1  A3  B3  S
4  5  1  A4  B4  S

In [24]: df2
Out[24]: 
     A    C    D
0    1    c   d1
1    6   c1   d1
2    9   c2   d2
3    4   c3   d3
4  NaN  NaN  NaN

现在你可以找到一个列相等的布尔数组,并使用基于loc的赋值修改df1 inplace而不需要额外的列:

In [26]: equal_rows = df1.A == df2.A

In [27]: df1.loc[equal_rows]
Out[27]: 
   A  B   C   D  E
0  1  1   A  B0  A
3  4  1  A3  B3  S

In [28]: df1.loc[equal_rows,['C','D']] = df2.loc[equal_rows,['C','D']]

In [29]: df1
Out[29]: 
   A  B   C   D  E
0  1  1   c  d1  A
1  2  1  A1  B1  A
2  3  1  A2  B2  S
3  4  1  c3  d3  S
4  5  1  A4  B4  S

如果你真的需要原来的df2:

In [30]: df2.dropna(how='all',axis=0, inplace=True)

In [31]: df2
Out[31]: 
   A   C   D
0  1   c  d1
1  6  c1  d1
2  9  c2  d2
3  4  c3  d3

原始答案

这是一种不太节省空间的笨重方式:

In [13]: merged = pd.merge(df1,df2,how='left', on=['A'])

In [14]: merged
Out[14]: 
   A  B C_x D_x  E  C_y  D_y
0  1  1   A  B0  A    c   d1
1  2  1  A1  B1  A  NaN  NaN
2  3  1  A2  B2  S  NaN  NaN
3  4  1  A3  B3  S   c3   d3
4  5  1  A4  B4  S  NaN  NaN

In [15]: merged.fillna({'C_y':df1.C,'D_y':df1.D},inplace=True)
Out[15]: 
   A  B C_x D_x  E C_y D_y
0  1  1   A  B0  A   c  d1
1  2  1  A1  B1  A  A1  B1
2  3  1  A2  B2  S  A2  B2
3  4  1  A3  B3  S  c3  d3
4  5  1  A4  B4  S  A4  B4

In [16]: merged.drop(['C_x','D_x'],axis=1,inplace=True)

In [17]: merged
Out[17]: 
   A  B  E C_y D_y
0  1  1  A   c  d1
1  2  1  A  A1  B1
2  3  1  S  A2  B2
3  4  1  S  c3  d3
4  5  1  S  A4  B4

如果你想要原来的名字:

In [20]: merged.rename(columns={"C_y":'C','D_y':'D'},inplace=True)

In [21]: merged
Out[21]: 
   A  B  E   C   D
0  1  1  A   c  d1
1  2  1  A  A1  B1
2  3  1  S  A2  B2
3  4  1  S  c3  d3
4  5  1  S  A4  B4