解决您的问题的一种可能方法是使用merge。检查df1中是否存在来自另一个数据帧(df2)的任何行(所有列)等同于确定两个数据帧的交集。可以使用以下功能完成此操作:
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')
新问题(评论),从df2中识别出了第一个数据帧(df1)中也存在的行,是否有可能采用pd.merge()的结果,然后从df2中删除行也在df1中
我不知道一种直接的方法来完成从df1中删除也从df2中删除行的任务。也就是说,您可以使用以下代码:
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)
可能存在一种更好的方式来完成该任务,但我不知道这种方法/功能。
如何从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
将上述DataFrames用于删除df1中也存在的df2中的行将导致以下结果:
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)