基于两列组合条件对 Pandas 数据框进行筛选

21

假设我有一个数据框,如下:

   a  b
0  1  2
1  2  3
2  4  2
3  4  3

我想筛选数据框,使得结果如下所示:

   a  b
0  1  2
3  4  3

即,我想通过过滤这两列,得到组合(1,2)(4,3)

如果我尝试这样做:

df1 = df[df['a'].isin([1,4]) & df['b'].isin([2,3])]

我得到了整个数据框,因为(1,3)(4,2)的组合也被包含在上述方法中。但是我只需要给定的组合。我有一个大型的元组列表,其中每个元组由两列组成,我希望基于这些元组的对应组合来过滤数据框。

此外,我不想将这两列合并为单个字符串,然后再进行过滤。


所以,你只想要(1,2)和(4,3),其余所有组合都应该被删除?对吗? - cph_sto
@cph_sto 是的,那就是我想要的。 - mayank agrawal
1
所以,您希望删除 (1,3),(2,3) 等...... - cph_sto
是的。具体来说,我有一个元组列表[(1,2), (4,3)],我想要在数据框中匹配这个列表中的元组组合的所有记录。 - mayank agrawal
2
尝试这个 - df[((df['a'] == 1) & (df['b'] ==2)) | ((df['a'] == 4) & (df['b'] ==3))],其中 df = pd.DataFrame({'a':[1,2,4,4],'b':[2,3,2,3]}) - cph_sto
3个回答

25

使用 -

df[df[['a', 'b']].apply(tuple, axis=1).isin([(1,2), (4,3)])]

输出

    a   b
0   1   2
3   4   3

说明

df[['a', 'b']].apply(tuple, axis=1)会返回一系列元组 -

0    (1, 2)
1    (2, 3)
2    (4, 2)
3    (4, 3)

.isin([(1,2), (4,3)]) 搜索所需的元组并返回一个布尔值序列。


10

按照@Vivek Kalyanarangan所述的元组比较方法是可行的,但在大型数据框的情况下,通过利用MultiIndex而不是使用apply函数进行元组创建可以显著提高速度:

例如,在您的情况下:

keep_tuples = [(1,2), (4,3)]
tuples_in_df = pd.MultiIndex.from_frame(df[["a","b"]])
df[tuples_in_df.isin(keep_tuples)]

这导致使用 apply 函数时,相比于一个大小为 1,000,000 X 2 的 df,速度提升了大约 5 倍。

3

另一个想法是将两列 (ab) 合并为字符串,并检查是否包含 1243,即:

df[df.astype(str).sum(axis = 1).isin([12, 43])]
#   a  b
#0  1  2
#3  4  3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接