我有两个数据框:
df1
Company Symbol ID Date Value
0 AAA Inc A 123 2019-12-31 10
1 AAA Inc A 123 2020-03-30 11
2 BBB Inc B 456 2019-03-31 12
3 FFF Inc F 653 2019-06-31 22
4 ZZZ Inc Z 999 2019-03-30 13
df2
Company Symbol ID Date Price
0 AAA Inc A 123 2019-12-31 10
1 AAA Inc A 123 2019-09-30 20
2 AAA Inc A 123 2019-06-31 30
3 AAA Inc A 123 2019-03-30 40
4 BBB Inc B 456 2019-12-31 50
5 BBB Inc B 456 2019-09-30 50
6 BBB Inc B 456 2019-06-31 90
7 BBB Inc B 456 2019-03-31 10
8 CCC Inc C 789 2019-12-31 79
9 CCC Inc C 789 2019-09-31 43
我想创建一个第3个数据帧,它是['Symbol', 'ID', 'Date']
中的所有df1
行,而不是df2
中的行。所以输出看起来像这样:
Company Symbol ID Date
0 AAA Inc A 123 2020-03-30
1 FFF Inc F 653 2019-06-31
2 ZZZ Inc Z 999 2019-03-30
我知道我可以做类似df3 = df1[~df1['Symbol'].isin(df2['Symbol'])]
的事情,但是经过一番研究后,似乎并没有一种将isin
用于多列的好方法。
我还检查了类似的questions,但没有发现仅能解决特定列的问题。
如果可能的话,我也想避免merging这两个数据帧。
那么我将如何实现呢?
答案 0 :(得分:2)
因为要避免使用merge
,所以这里有一个可能的解决方案是将Index.isin
与MultiIndex
进行比较:
cols = ['Symbol', 'ID', 'Date']
df3 = df1[~df1.set_index(cols).index.isin(df2.set_index(cols).index)]
print (df3)
Company Symbol ID Date Value
1 AAA Inc A 123 2020-03-30 11
3 FFF Inc F 653 2019-06-31 22
4 ZZZ Inc Z 999 2019-03-30 13
或将列转换为元组:
cols = ['Symbol', 'ID', 'Date']
df3 = df1[~df1[cols].apply(tuple, 1).isin(df2[cols].apply(tuple, 1))]
对于使用merge
和indicator
参数的比较解决方案:
cols = ['Symbol', 'ID', 'Date']
df3 = (df1.merge(df2, on=cols, indicator=True, how='left', suffixes=('','_'))
.query("_merge == 'left_only'")[df1.columns])
print (df3)
Company Symbol ID Date Value
1 AAA Inc A 123 2020-03-30 11
3 FFF Inc F 653 2019-06-31 22
4 ZZZ Inc Z 999 2019-03-30 13