pandas-按另一个数据帧按行元素筛选数据帧

2024-10-05 18:40:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧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

Tags: 数据方法df元组df1df2isindfc
3条回答

我认为这是一种非常简单的方法,当您希望基于来自另一个数据帧的多个列或甚至基于自定义列表筛选一个数据帧时。

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']})

#values of df2 columns 'c' and 'l' that will be used to filter df1
idxs = list(zip(df2.c.values, df2.l.values)) #[('A', 'b'), ('C', 'a')]

#so df1 is filtered based on the values present in columns c and l of df2 
df1 = df1[pd.Series(list(zip(df1.c, df1.l)), index=df1.index).isin(idxs)]

在由所需列构造的多索引上使用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)]

enter image description here

我认为这改进了@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

enter image description here

# extract desired columns where marker is NaN
joined[pd.isnull(joined['marker'])][df1.columns]

enter image description here

可能有一种不使用临时数组的方法,但是我想不出一种。只要你的数据不是很大,上面的方法应该是一个快速和充分的答案。

这很简洁,效果很好:

df1 = df1[~df1.index.isin(df2.index)]

相关问题 更多 >