Python 左键联接并更新现有列

Python 左键联接并更新现有列,python,pandas,Python,Pandas,我刚接触熊猫,似乎无法使用合并功能: >>> left >>> right a b c a c d 0 1 4 9 0 1 7 13 1 2 5 10 1 2 8 14 2 3 6 11 2 3 9 15 3 4 7 12 对于列a上的左连接,我想通过连接键更新公共列。注:c列中的最后一个值来自左表,因为不存在匹配项 >>> f

我刚接触熊猫,似乎无法使用合并功能:

>>> left       >>> right
   a  b   c       a  c   d 
0  1  4   9    0  1  7  13
1  2  5  10    1  2  8  14
2  3  6  11    2  3  9  15
3  4  7  12    
对于列a上的左连接,我想通过连接键更新公共列。注:c列中的最后一个值来自左表,因为不存在匹配项

>>> final       
   a  b   c   d 
0  1  4   7   13
1  2  5   8   14
2  3  6   9   15
3  4  7   12  NAN 
我应该如何使用Pandas merge函数来实现这一点?谢谢。

您可以在
之间使用
how='left'
,在
'a'
列中使用
merge()

In [74]: final = left.merge(right, on='a', how='left')

In [75]: final
Out[75]:
   a  b  c_x  c_y   d
0  1  4    9    7  13
1  2  5   10    8  14
2  3  6   11    9  15
3  4  7   12  NaN NaN
c_y
中的
NaN
值替换为
c_x

In [76]: final['c'] = final['c_y'].fillna(final['c_x'])

In [77]: final
Out[77]:
   a  b  c_x  c_y   d   c
0  1  4    9    7  13   7
1  2  5   10    8  14   8
2  3  6   11    9  15   9
3  4  7   12  NaN NaN  12
删除不需要的列,就会得到结果

In [79]: final.drop(['c_x', 'c_y'], axis=1)
Out[79]:
   a  b   d   c
0  1  4  13   7
1  2  5  14   8
2  3  6  15   9
3  4  7 NaN  12
您可以使用
a'
列上的
how='left'
left
right
之间使用
merge()

In [74]: final = left.merge(right, on='a', how='left')

In [75]: final
Out[75]:
   a  b  c_x  c_y   d
0  1  4    9    7  13
1  2  5   10    8  14
2  3  6   11    9  15
3  4  7   12  NaN NaN
c_y
中的
NaN
值替换为
c_x

In [76]: final['c'] = final['c_y'].fillna(final['c_x'])

In [77]: final
Out[77]:
   a  b  c_x  c_y   d   c
0  1  4    9    7  13   7
1  2  5   10    8  14   8
2  3  6   11    9  15   9
3  4  7   12  NaN NaN  12
删除不需要的列,就会得到结果

In [79]: final.drop(['c_x', 'c_y'], axis=1)
Out[79]:
   a  b   d   c
0  1  4  13   7
1  2  5  14   8
2  3  6  15   9
3  4  7 NaN  12

这里有一种使用
join
的方法:

In [632]: t = left.set_index('a').join(right.set_index('a'), rsuffix='_right')

In [633]: t
Out[633]: 
   b   c  c_right   d
a                    
1  4   9        7  13
2  5  10        8  14
3  6  11        9  15
4  7  12      NaN NaN
现在,我们要将
c\u right
(来自
right
dataframe)的空值设置为
c
列中来自
left
dataframe的值。使用取自@John Galt答案的方法更新了以下流程

In [657]: t['c_right'] = t['c_right'].fillna(t['c'])

In [658]: t
Out[658]: 
   b   c  c_right   d
a                    
1  4   9        7  13
2  5  10        8  14
3  6  11        9  15
4  7  12       12 NaN

In [659]: t.drop('c_right', axis=1)
Out[659]: 
   b   c   d
a           
1  4   9  13
2  5  10  14
3  6  11  15
4  7  12 NaN

这里有一种使用
join
的方法:

In [632]: t = left.set_index('a').join(right.set_index('a'), rsuffix='_right')

In [633]: t
Out[633]: 
   b   c  c_right   d
a                    
1  4   9        7  13
2  5  10        8  14
3  6  11        9  15
4  7  12      NaN NaN
现在,我们要将
c\u right
(来自
right
dataframe)的空值设置为
c
列中来自
left
dataframe的值。使用取自@John Galt答案的方法更新了以下流程

In [657]: t['c_right'] = t['c_right'].fillna(t['c'])

In [658]: t
Out[658]: 
   b   c  c_right   d
a                    
1  4   9        7  13
2  5  10        8  14
3  6  11        9  15
4  7  12       12 NaN

In [659]: t.drop('c_right', axis=1)
Out[659]: 
   b   c   d
a           
1  4   9  13
2  5  10  14
3  6  11  15
4  7  12 NaN

一种方法是将a列设置为索引,然后:

注意:
update
只进行左连接(而不是合并),因此除了设置索引外,还需要包括
left\u a
中不存在的其他列


一种方法是将a列设置为索引,然后:

注意:
update
只进行左连接(而不是合并),因此除了设置索引外,还需要包括
left\u a
中不存在的其他列

另一种方法是这样使用:

您可以计算要更新的两个数据帧列名称的交集,以将其传递给函数的“on=”参数

它不会像Zero的解决方案那样创建必须删除的不需要的列

编辑: NaN值可能会将同一列中的整数更改为浮点数。

另一种方法是这样使用:

您可以计算要更新的两个数据帧列名称的交集,以将其传递给函数的“on=”参数

它不会像Zero的解决方案那样创建必须删除的不需要的列

编辑: NaN值可能会将同一列中的整数更改为浮点。

很好,但它不允许您指定要连接的列,更重要的是,如果其他数据帧具有NaN值,这些NaN值将不会覆盖原始数据帧中的非NaN值。对我来说,这是不受欢迎的行为

这里有一个我用来解决这些问题的自定义方法。它是新写的,所以用户要小心

join_insertion() 示例使用 顺便说一句,这是我在R的data.table包中严重遗漏的内容之一。对于data.table,这与
x[y,Foo:=i.Foo,on=c(“a”,“b”)]一样简单。

很好,但它不允许您指定要连接的列,更重要的是,如果其他数据帧具有NaN值,则这些NaN值不会覆盖原始数据帧中的非NaN值。对我来说,这是不受欢迎的行为

这里有一个我用来解决这些问题的自定义方法。它是新写的,所以用户要小心

join_insertion() 示例使用
顺便说一句,这是我在R的data.table包中严重遗漏的内容之一。对于data.table,这就像
x[y,Foo:=i.Foo,on=c(“a”,“b”)]

一样简单,因为fillna(使用不同的列)非常整洁!与公认的答案相比,我更喜欢这种方法,因为它不依赖于两个数据帧有一个共同的连接键变量(本例中为“a”)。当我使用此代码时,我始终会遇到此错误:FutureWarning:传递列表likes to.loc或[]以及任何缺少的标签将在将来引发KeyError,您可以使用.reindex()作为替代方案。我唯一的想法是我的dfs可能不共享相同的列?这不是原来的答案应该是正确的吗?这个答案是最具python风格的方式,fillna(有一个不同的专栏)非常整洁!与公认的答案相比,我更喜欢这种方法,因为它不依赖于两个数据帧有一个共同的连接键变量(本例中为“a”)。当我使用此代码时,我始终会遇到此错误:FutureWarning:传递列表likes to.loc或[]以及任何缺少的标签将在将来引发KeyError,您可以使用.reindex()作为替代方案。我唯一的想法是我的dfs可能不共享相同的列?这不是最初的答案应该纠正的吗?这个答案是最具python风格的解决方法警告那些实现这个解决方案的人:在某些情况下,整数数据类型被更改为float!警告:不推荐使用
loc
添加新列。请像这样使用
left\u a.reindex(columns=left\u a.columns.union(right\u a.columns))
。欢迎使用。你给了我我需要的答案,并建立在;)警告:根据,
DataFrame.update()
将不会用nan值覆盖非nan值。对于实施此解决方案的用户,警告:在某些情况下,整数数据类型将更改为浮点型!警告:不推荐使用
loc
添加新列。请像这样使用
left\u a.reindex(columns=left\u a.columns.union(right\u a.columns))
。欢迎使用。你给了我我需要的答案,并建立在;)警告:根据,
DataFrame.update()
不会用nan值覆盖非nan值。Somethin