Python 来自两个数据帧的不相交记录集
有没有一种简单的方法可以在基于多索引的两个数据帧之间找到不相交的记录集(两个原始数据帧中的每一个都会留下什么,而这两个原始数据帧不包括在生成的内部连接中) 我是否遗漏了一些显而易见的东西,或者我必须自己花一些时间来实现这种功能 我试图通过查找两个数据帧的多索引键集之间的对称差异来实现这一点,但事实证明这很困难。我一直在努力让它发挥作用。我的另一个选择似乎更容易一些,就是添加一个伪整数列,它可以充当不同的单个索引,即使在我进行多索引合并之后也会被保留,这样我就可以在这个事实上的单个键上使用python集运算符Python 来自两个数据帧的不相交记录集,python,pandas,Python,Pandas,有没有一种简单的方法可以在基于多索引的两个数据帧之间找到不相交的记录集(两个原始数据帧中的每一个都会留下什么,而这两个原始数据帧不包括在生成的内部连接中) 我是否遗漏了一些显而易见的东西,或者我必须自己花一些时间来实现这种功能 我试图通过查找两个数据帧的多索引键集之间的对称差异来实现这一点,但事实证明这很困难。我一直在努力让它发挥作用。我的另一个选择似乎更容易一些,就是添加一个伪整数列,它可以充当不同的单个索引,即使在我进行多索引合并之后也会被保留,这样我就可以在这个事实上的单个键上使用pyth
[请注意,这与此问题相关,但略有不同,因为此合并不是基于多索引对象,而是基于dataframe列中的值:我认为您找到对称差异的方法是可行的
In [97]: from numpy import random
In [98]: arrays1 = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
....: ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
In [99]: arrays2 = [['bar', 'baz', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], [
....: 'one', 'one', 'two', 'three', 'one', 'two', 'one', 'three']]
In [100]: tuples1 = zip(*arrays1)
In [101]: tuples2 = zip(*arrays2)
In [102]: index1 = MultiIndex.from_tuples(tuples1, names=['first', 'second'])
In [103]: index2 = MultiIndex.from_tuples(tuples2, names=['first', 'second'])
In [104]: df1 = pd.DataFrame(random.randn(8, 2), index=index1)
In [105]: df2 = pd.DataFrame(random.randn(8, 2), index=index2)
In [106]: df1
Out[106]:
0 1
first second
bar one 0.613378 -0.400247
baz one -3.005834 0.004879
two 0.066539 -0.289100
three -0.020099 0.644226
foo one -0.461458 -1.621812
two 0.286655 0.110588
qux one 0.363648 -0.271281
three 1.707787 -1.832602
In [107]: df2
Out[107]:
0 1
first second
bar one -1.010482 -0.023373
baz one -0.040335 1.553905
two -0.080283 -0.571686
three -0.985722 -0.795481
foo one 0.623122 2.124316
two -0.493333 -0.343462
qux one -1.346753 -1.343945
three -0.053497 -0.382402
In [108]: sym_diff = (df1.index - df2.index).union(df2.index - df1.index)
In [109]: sym_diff
Out[109]:
MultiIndex
[(u'baz', u'three'), (u'qux', u'three')]
我不确定为什么在多索引上没有对称差分法。使用的测试数据与Tomaugsurger概述的相同
import pandas as pd
import numpy as np
# create a test data set
arrays1 = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
arrays2 = [['bar', 'baz', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
['one', 'one', 'two', 'three', 'one', 'two', 'one', 'three']]
tuples1 = zip(*arrays1)
tuples2 = zip(*arrays2)
index1 = pd.MultiIndex.from_tuples(tuples1, names=['first', 'second'])
index2 = pd.MultiIndex.from_tuples(tuples2, names=['first', 'second'])
df1 = pd.DataFrame(np.random.randn(8, 2), index=index1)
df2 = pd.DataFrame(np.random.randn(8, 2), index=index2)
这将产生以下两个表
0 1
first second
bar one -0.579214 0.261575
two 0.912683 -0.475463
baz one -0.295739 -0.586646
two 0.031916 0.199812
foo one -0.724781 -1.245275
two -0.824759 2.270161
qux one 0.638533 0.537306
two -0.988444 -1.076636
及
然后,您可以通过以下方式获得不相交的数据帧:
df1[~df1.index.isin(df2.index)].append(df2[~df2.index.isin(df1.index)])
导致
0 1
first second
bar two 0.912683 -0.475463
qux two -0.988444 -1.076636
baz three 0.212799 -1.592317
qux three 0.610065 0.028249
这就是你想要的吗?好的,当我将第103行更改为index2,将第108行的最后一项更改为df1.index时,这就行了。唯一的问题是多重索引和数据帧的大小,计算符号差异几乎需要一分钟。我认为你的方法看起来更优雅,但我最终做的略有不同。我在合并之前重新生成索引,然后合并两次,第一次保留一帧的索引,第二次保留另一帧的索引。然后,我在每个原始列中按索引删除匹配的行。这是更多的代码,但花了大约5秒钟。今天晚些时候我会写下我的解决方案a,以防有人看到。很抱歉输入错误,你在这两个方面都是对的。可惜我的路太慢了。你的指数提前排序了吗?我想知道这是花费最多的时间还是集合运算。
0 1
first second
bar two 0.912683 -0.475463
qux two -0.988444 -1.076636
baz three 0.212799 -1.592317
qux three 0.610065 0.028249