我有一个这样的数据框:
data1 = pd.DataFrame([['a','z',0],['a','y',20],['b','z',1]],columns=['id1','id2','number'])
data2 = pd.DataFrame([['a','y',1],['a','y',1],['b','z',0]],columns=['id1','id2','number'])
我想返回data1而不是data2的记录(由id1和id2连接)。
在这种情况下,我只想让它返回一条记录[' a'' z',0],因为两者都是[' a',& #39; y']和[' b'' z']确实存在于data2中。
答案 0 :(得分:4)
我认为还有另一种方式。如果我们将两列都设置为索引,我们可以使用.isin
方法过滤掉所需的内容:
data1.set_index(['id1', 'id2'], inplace=True)
data2.set_index(['id1', 'id2'], inplace=True)
data1[~data1.index.isin(data2.index)].reset_index()
收率:
id1 id2 number
0 a z 0
无论您在number
中拥有什么。
答案 1 :(得分:1)
这个有点棘手,通常当我们想要使用多个条件过滤掉行时,我们会做类似的事情:
In [39]:
data1[(data1.id1 != data2.id1) & (data1.id2 != data2.id2)]
Out[39]:
Empty DataFrame
Columns: [id1, id2, number]
Index: []
但这不会产生任何行,因为不满足条件,因为至少有一个id值匹配。
所以我们真正想要的是将两列用作id列,然后过滤掉仅在data1中的行。
为实现这一目标,我们可以先执行左合并:
In [33]:
merged = data1.merge(data2, on=['id1', 'id2'], how='left')
merged
Out[33]:
id1 id2 number_x number_y
0 a z 0 NaN
1 a y 20 1
2 a y 20 1
3 b z 1 0
现在我们只需要右侧为空的行,因为这表示复合索引值不存在:
In [36]:
merged_null = merged[merged.number_y.isnull()]
merged_null
Out[36]:
id1 id2 number_x number_y
0 a z 0 NaN
现在,我们可以使用此选项从原始数据框中选择我们的行isin
来选择id1 ad id2中的ID值:
In [38]:
data1[(data1.id1.isin(merged_null['id1']) ) & (data1.id2.isin(merged_null['id2']))]
Out[38]:
id1 id2 number
0 a z 0