过滤掉一些不包含 python 列的特定情况的组

Filter out some group that don’t contain specific case of a column in python

我是 python 的新手,我有一个关于如何过滤掉一些不包含任何女性案例的组(按“日期”分组)的问题。假设我有一个数据框如下:

import pandas as pd
import numpy as np

exam_data  = {
        'date': ['2000-1', '2000-1', '2000-1', '2000-2', '2000-2', '2000-3', '2000-4', '2000-4', '2000-5', '2000-5','2000-5'],
        'sex': ['M', 'M', 'F', 'M', 'M', 'F', 'M', 'M', 'F', 'F', 'M'],
        'qualify': ['yes', 'no', 'yes', 'no', 'no', 'yes', 'yes', 'no', 'no', 'yes', 'no']}
df_exam = pd.DataFrame(exam_data)

我已经试过了,这似乎是正确的,但我觉得它太具体了,因为我使用了包含 'F':

的字符串
df_filter = df_exam.groupby("date").filter(lambda gr: gr["sex"].str.contains("F").any())

有没有其他算法比这个更有效或者比这个更实用?

非常感谢您的评论。

测试是验证算法是否更有效的最终方法;然而,乍一看,如果你能避免匿名函数(lambda),理论上你应该获得更多的性能:

df_exam.loc[df_exam.sex.eq('F').groupby(df_exam.date).transform('any')]
Out[32]: 
      date sex qualify
0   2000-1   M     yes
1   2000-1   M      no
2   2000-1   F     yes
5   2000-3   F     yes
8   2000-5   F      no
9   2000-5   F     yes
10  2000-5   M      no

上面的代码是将一个系列分组到另一个系列(pandas索引对齐在分组之前开始); transform 使结果与原始数据帧的长度相同

为了更好的性能永远不要使用 filter,更好的方法是通过 GroupBy.transform with mask and filter in boolean indexing:

创建布尔掩码
df_filter = df_exam[df_exam["sex"].eq("F").groupby(df_exam["date"]).transform('any')]

或者替代也很好,取决于数据,如果更好,如 transform - 按条件获取所有 dates 并在 boolean indexing with Series.isin 中过滤:

dates = df_exam.loc[df_exam["sex"].eq("F"), 'date'].unique()

df_filter = df_exam[df_exam["date"].isin(dates)]