我有一个数据帧 df1
,它看起来像:
c k l
0 A 1 a
1 A 2 b
2 B 2 a
3 C 2 a
4 C 2 d
另一个叫做 df2
像: c l
0 A b
1 C a
我想过滤 df1
只保留不在 df2
中的值。要过滤的值预计为 (A,b)
和 (C,a)
元组。到目前为止,我尝试应用 isin
方法:d = df[~(df['l'].isin(dfc['l']) & df['c'].isin(dfc['c']))]
在我看来这太复杂了,它返回: c k l
2 B 2 a
4 C 2 d
但我期待: c k l
0 A 1 a
2 B 2 a
4 C 2 d
最佳答案
您可以在由所需列构造的多索引上使用 isin
有效地执行此操作:
df1 = pd.DataFrame({'c': ['A', 'A', 'B', 'C', 'C'],
'k': [1, 2, 2, 2, 2],
'l': ['a', 'b', 'a', 'a', 'd']})
df2 = pd.DataFrame({'c': ['A', 'C'],
'l': ['b', 'a']})
keys = list(df2.columns.values)
i1 = df1.set_index(keys).index
i2 = df2.set_index(keys).index
df1[~i1.isin(i2)]
我认为这改进了@IanS 的类似解决方案,因为它不假设任何列类型(即它可以处理数字和字符串)。
(以上答案是编辑。以下是我的初步答案)
有趣的!这是我以前从未遇到过的事情......我可能会通过合并两个数组来解决它,然后删除定义
df2
的行。这是一个使用临时数组的示例:df1 = pd.DataFrame({'c': ['A', 'A', 'B', 'C', 'C'],
'k': [1, 2, 2, 2, 2],
'l': ['a', 'b', 'a', 'a', 'd']})
df2 = pd.DataFrame({'c': ['A', 'C'],
'l': ['b', 'a']})
# create a column marking df2 values
df2['marker'] = 1
# join the two, keeping all of df1's indices
joined = pd.merge(df1, df2, on=['c', 'l'], how='left')
joined
# extract desired columns where marker is NaN
joined[pd.isnull(joined['marker'])][df1.columns]
可能有一种方法可以在不使用临时数组的情况下执行此操作,但我想不出一个方法。只要您的数据不是很大,上述方法应该是一个快速而充分的答案。
关于python - pandas - 按行元素通过另一个数据帧过滤数据帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33282119/