我有df1
和df2
:
df1 = pd.DataFrame([[1,1,1,1],[2,2,1,1],[0,0,1,1],[1,1,1,1],[2,2,1,1],[0,0,4,1]],
columns=['col1','col2','col3','col4'])
df2 = pd.DataFrame([[1,1,1,1],[3,3,1,1],[0,0,1,1],[1,1,5,1],[3,3,1,1],[0,0,1,1]],
columns=['col1','col2','col3','col4'])
我删除了重复的行:
df1 = df1.drop_duplicates(subset=['col1', 'col2', 'col3'])
df2 = df2.drop_duplicates(subset=['col1', 'col2', 'col3'])
因此每个df由唯一的行组成。但是两个df之间有一些重叠:
col1 col2 col3 col4
0 1 1 1 1
1 2 2 1 1
2 0 0 1 1
5 0 0 4 1
col1 col2 col3 col4
0 1 1 1 1
1 3 3 1 1
2 0 0 1 1
3 1 1 5 1
我的实际df1
和df2
的形状大约为(5000000,23),并包含int,float和object字段。
开始编辑:
我想创建df1_uniq
(在df1中但不在df2中)和df2_uniq
(在df2中但不在df1中。)
df1_iniq:
col1 col2 col3 col4
1 2 2 1 1
5 0 0 4 1
df2_uniq:
col1 col2 col3 col4
1 3 3 1 1
3 1 1 5 1
结束编辑
在集合符号中,我认为这将是df1.difference(df2)
和df2.difference(df1)
,但是运行该代码时会得到空集合。请注意,比较每个df 工作中的单个col,例如
set(df_1[field].unique()).difference(set(df_2[field].unique()))
返回[2]
。
另一种方法是遍历每个df,如果df1 [i]等于df2中的任何行,则将该行都放在两个df中。但这是一种O(n ** 2)方法,将需要很长时间。
是否还有更Python化,泛滥的方式来做到这一点?
答案 0 :(得分:2)
您可以将merge
与indicator=True
结合使用:
u = df1.merge(df2, how='outer', indicator=True)
df3 = u.query('_merge == "left_only"').drop('_merge', 1)
df4 = u.query('_merge == "right_only"').drop('_merge', 1)
df3
col1 col2 col3 col4
1 2 2 1 1
3 0 0 4 1
df4
col1 col2 col3 col4
4 3 3 1 1
5 1 1 5 1
如果df1
和df2
的列名不同,请确保它们都相同:
df1.columns = df2.columns
如果还需要保留索引,则可以在合并之前先将其重置,然后再进行设置。
u, v = df1.reset_index(), df2.reset_index()
w = (u.merge(v, how='outer', on=df1.columns.tolist(), indicator=True)
.fillna({'index_x': -1, 'index_y': -1}, downcast='infer'))
w
index_x col1 col2 col3 col4 index_y _merge
0 0 1 1 1 1 0 both
1 1 2 2 1 1 -1 left_only
2 2 0 0 1 1 2 both
3 5 0 0 4 1 -1 left_only
4 -1 3 3 1 1 1 right_only
5 -1 1 1 5 1 3 right_only
现在,
df3 = (w.query('_merge == "left_only"')
.set_index('index_x')
.drop(['_merge', 'index_y'], 1)
.rename_axis([None], axis=0))
df4 = (w.query('_merge == "right_only"')
.set_index('index_y')
.drop(['_merge', 'index_x'], 1)
.rename_axis([None], axis=0))
df3
col1 col2 col3 col4
1 2 2 1 1
5 0 0 4 1
df4
col1 col2 col3 col4
1 3 3 1 1
3 1 1 5 1
答案 1 :(得分:0)
假设您要比较行集,则需要将每行转换为可哈希的对象,例如元组:
set([tuple(x) for x in df1.values]) - set([tuple(x) for x in df2.values])