如何在熊猫中进行左外连接排除
Posted
技术标签:
【中文标题】如何在熊猫中进行左外连接排除【英文标题】:How to do left outer join exclusion in pandas 【发布时间】:2018-11-05 16:29:30 【问题描述】:我有两个数据框,A 和 B,我想在 A 中而不是 B 中获取它们,就像左上角正下方的那个一样。
数据框 A 具有列 ['a','b' + others]
,B 具有列 ['a','b' + others]
。没有 NaN 值。我尝试了以下方法:
1.
dfm = dfA.merge(dfB, on=['a','b'])
dfe = dfA[(~dfA['a'].isin(dfm['a']) | (~dfA['b'].isin(dfm['b'])
2.
dfm = dfA.merge(dfB, on=['a','b'])
dfe = dfA[(~dfA['a'].isin(dfm['a']) & (~dfA['b'].isin(dfm['b'])
3.
dfe = dfA[(~dfA['a'].isin(dfB['a']) | (~dfA['b'].isin(dfB['b'])
4.
dfe = dfA[(~dfA['a'].isin(dfB['a']) & (~dfA['b'].isin(dfB['b'])
但是当我得到len(dfm)
和len(dfe)
时,它们的总和不等于dfA
(相差几个数字)。我已经尝试在虚拟案例和 #1 作品上执行此操作,所以也许我的数据集可能有一些我无法重现的特性。
这样做的正确方法是什么?
【问题讨论】:
问题出在(~dfA['a'].isin(dfm['a']) | (~dfB['b'].isin(dfm['b']))
表达式中。例如,如果在 dfm
中有 (a=1, b=1), (a=2, b=2)
,在 dfA 中有 (a=1, b=2)
,则此表达式返回 False
。
@user3063243 知道了。我还发布了我所做的其他尝试,但没有一个是正确的。你知道正确的方法吗?
好图...
@liang 图片不是我的……我是从 Google 图片的某个地方得到的
相关:如果你有兴趣学习如何正确合并列或索引,可以参考我最近写的这个规范:Pandas Merging 101。
【参考方案1】:
查看this link
df = pd.merge(dfA, dfB, on=['a','b'], how="outer", indicator=True)
df = df[df['_merge'] == 'left_only']
一个班轮:
df = pd.merge(dfA, dfB, on=['a','b'], how="outer", indicator=True
).query('_merge=="left_only"')
【讨论】:
为什么是how="outer"?!为什么不“离开”? @pedrambashirihow="left"
在这种情况下也可以工作(左外排除)
@irene 谢谢,我个人更喜欢 left,因为它更直观且与 Sql 内联【参考方案2】:
我认为它会类似于以下示例:Pandas left outer join multiple dataframes on multiple columns
dfe = pd.merge(dFA, dFB, how='left', on=['a','b'], indicator=True)
dfe[dfe[_merge] == 'left_only']
【讨论】:
嗨贾斯汀,这将对应于左上图。它将包括它们共有的行。 接受编辑——这个答案也有效(并且基于上面 phi 的答案)。 我认为这需要是 dfe[dfe['_merge'] == "left_only"]以上是关于如何在熊猫中进行左外连接排除的主要内容,如果未能解决你的问题,请参考以下文章