【发布时间】:2018-05-05 20:11:14
【问题描述】:
我熟悉在 pandas 中执行 join
pd.merge(A,B,on='key',how='inner')
【问题讨论】:
标签: python sql database pandas
我熟悉在 pandas 中执行 join
pd.merge(A,B,on='key',how='inner')
【问题讨论】:
标签: python sql database pandas
设置
A = pd.DataFrame(dict(key=range(0, 5), col1=list('abcde')))
B = pd.DataFrame(dict(key=range(2, 7), col2=list('vwxyz')))
print(A, B, sep='\n' * 2)
col1 key
0 a 0
1 b 1
2 c 2
3 d 3
4 e 4
col2 key
0 v 2
1 w 3
2 x 4
3 y 5
4 z 6
pd.DataFrame.merge
最直接的方法是使用indicator 参数。
A.merge(B, 'outer', indicator=True)
col1 key col2 _merge
0 a 0 NaN left_only
1 b 1 NaN left_only
2 c 2 v both
3 d 3 w both
4 e 4 x both
5 NaN 5 y right_only
6 NaN 6 z right_only
那么我们可以使用pd.DataFrame.query
A - B
A.merge(B, 'outer', indicator=True).query('_merge == "left_only"')
col1 key col2 _merge
0 a 0 NaN left_only
1 b 1 NaN left_only
B - A
A.merge(B, 'outer', indicator=True).query('_merge == "right_only"')
col1 key col2 _merge
5 NaN 5 y right_only
6 NaN 6 z right_only
对称差分
A.merge(B, 'outer', indicator=True).query('_merge != "both"')
col1 key col2 _merge
0 a 0 NaN left_only
1 b 1 NaN left_only
5 NaN 5 y right_only
6 NaN 6 z right_only
pd.Series.isin(大部分)但是,我想简单地使用 pd.Series.isin 作为布尔掩码。
A - B
A[~A.key.isin(B.key)]
col1 key
0 a 0
1 b 1
B - A
B[~B.key.isin(A.key)]
col2 key
3 y 5
4 z 6
对称差分
A[~A.key.isin(B.key)].append(B[~B.key.isin(A.key)])
或者
A.append(B).drop_duplicates('key', keep=False)
col1 col2 key
0 a NaN 0
1 b NaN 1
3 NaN y 5
4 NaN z 6
【讨论】:
虽然 piRSquared 的回答非常好,但这是另一种方法:
import pandas as pd
创建数据帧A 和B:
A = pd.DataFrame({'key': range(1, 6), 'A': ['a'] * 5})
B = pd.DataFrame({'key': range(3, 8), 'B': ['b'] * 5})
示例 A 的解决方案(即左不包括连接):
首先执行左连接,然后只保留A 中在B 中没有对应行的列:
pd.merge(A, B, on = 'key', how = 'left')[~A.key.isin(B.key)]
key A B
0 1 a NaN
1 2 a NaN
例如 B 的解决方案(即右排除连接): 与解决方案 A 非常相似,但具有右连接:
pd.merge(A, B, on = 'key', how = 'right')[~B.key.isin(A.key)]
key A B
3 6 NaN b
4 7 NaN b
例如 C 的解决方案(即外部不包括连接): 首先执行全外连接:
outer = pd.merge(A, B, on = 'key', how = 'outer')
然后过滤A和B中在B和A中没有对应键的行:
outer[outer.key.isin(list(A.key[~A.key.isin(B.key)]) + list(B.key[~B.key.isin(A.key)]))]
key A B
0 1 a NaN
1 2 a NaN
5 6 NaN b
6 7 NaN b
【讨论】: