解决您的问题的一种可能的解决方案是使用merge。检查另一个数据帧 (df2) 中的任何行(所有列)是否存在于 df1 中相当于确定两个数据帧的交集。这可以使用以下函数来完成:
pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner')
例如,如果 df1 是
A B C D
0 0.403846 0.312230 0.209882 0.397923
1 0.934957 0.731730 0.484712 0.734747
2 0.588245 0.961589 0.910292 0.382072
3 0.534226 0.276908 0.323282 0.629398
4 0.259533 0.277465 0.043652 0.925743
5 0.667415 0.051182 0.928655 0.737673
6 0.217923 0.665446 0.224268 0.772592
7 0.023578 0.561884 0.615515 0.362084
8 0.346373 0.375366 0.083003 0.663622
9 0.352584 0.103263 0.661686 0.246862
df2 定义为:
A B C D
0 0.259533 0.277465 0.043652 0.925743
1 0.667415 0.051182 0.928655 0.737673
2 0.217923 0.665446 0.224268 0.772592
3 0.023578 0.561884 0.615515 0.362084
4 0.346373 0.375366 0.083003 0.663622
5 2.000000 3.000000 4.000000 5.000000
6 14.000000 15.000000 16.000000 17.000000
功能pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner')
产生:
A B C D
0 0.259533 0.277465 0.043652 0.925743
1 0.667415 0.051182 0.928655 0.737673
2 0.217923 0.665446 0.224268 0.772592
3 0.023578 0.561884 0.615515 0.362084
4 0.346373 0.375366 0.083003 0.663622
结果是 df1 和 df2 中的所有行(所有列)。
如果 df1 和 df2 中的列不相同,我们还可以修改此示例,只需比较列子集的相同行值。如果我们修改原来的例子:
df1 = pd.DataFrame(np.random.rand(10,4),columns=list('ABCD'))
df2 = df1.ix[4:8]
df2.reset_index(drop=True,inplace=True)
df2.loc[-1] = [2, 3, 4, 5]
df2.loc[-2] = [14, 15, 16, 17]
df2.reset_index(drop=True,inplace=True)
df2 = df2[['A', 'B', 'C']] # df2 has only columns A B C
然后我们可以使用以下命令查看公共列common_cols = list(set(df1.columns) & set(df2.columns))
两个数据框之间然后合并:
pd.merge(df1, df2, on=common_cols, how='inner')
EDIT:新问题(评论),确定了第一个数据帧(df1)中也存在的 df2 行,是否可以获取 pd.merge() 的结果,然后删除 df2 中也存在的行在 df1 中
我不知道有什么简单的方法可以完成从 df2 中删除 df1 中也存在的行的任务。也就是说,您可以使用以下内容:
ds1 = set(tuple(line) for line in df1.values)
ds2 = set(tuple(line) for line in df2.values)
df = pd.DataFrame(list(ds2.difference(ds1)), columns=df2.columns)
可能存在更好的方法来完成该任务,但我不知道这样的方法/功能。
EDIT 2:如何从 df2 中删除也存在于 df1 中的行,如@WR 答案所示。
提供的方法df2[~df2['A'].isin(df12['A'])]
不考虑所有类型的情况。考虑以下数据帧:
df1:
A B C D
0 6 4 1 6
1 7 6 6 8
2 1 6 2 7
3 8 0 4 1
4 1 0 2 3
5 8 4 7 5
6 4 7 1 1
7 3 7 3 4
8 5 2 8 8
9 3 2 8 4
df2:
A B C D
0 1 0 2 3
1 8 4 7 5
2 4 7 1 1
3 3 7 3 4
4 5 2 8 8
5 1 1 1 1
6 2 2 2 2
df12:
A B C D
0 1 0 2 3
1 8 4 7 5
2 4 7 1 1
3 3 7 3 4
4 5 2 8 8
使用上述 DataFrame 的目的是从 df2 中删除也存在于 df1 中的行,将导致以下结果:
A B C D
0 1 1 1 1
1 2 2 2 2
行 (1, 1, 1, 1) 和 (2, 2, 2, 2) 位于 df2 中,而不位于 df1 中。不幸的是,使用提供的方法(df2[~df2['A'].isin(df12['A'])]
) 结果是:
A B C D
6 2 2 2 2
发生这种情况是因为在交集 DataFrame(即 (1, 0, 2, 3))和 df2 中都找到了 A 列中的值 1,因此删除了 (1, 0, 2, 3) 和 (1, 1, 1, 1).这是无意的,因为行 (1, 1, 1, 1) 不在 df1 中,不应删除。
我认为以下内容将提供解决方案。它创建一个虚拟列,稍后用于将 DataFrame 子集化为所需的结果:
df12['key'] = 'x'
temp_df = pd.merge(df2, df12, on=df2.columns.tolist(), how='left')
temp_df[temp_df['key'].isnull()].drop('key', axis=1)