【问题标题】:Filter out some group that don’t contain specific case of a column in python过滤掉一些不包含python中列的特定情况的组
【发布时间】:2021-12-16 19:09:15
【问题描述】:

我是 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())

还有其他算法比这更有效,或者比这更实用吗?

非常感谢您的 cmets。

【问题讨论】:

  • df_exam.groupby("date").filter(lambda gr: gr["sex"].eq("F").any()) 也可以使用

标签: python pandas pandas-groupby filtering


【解决方案1】:

为了获得更好的性能,永远不要使用filter,更好的是由GroupBy.transform创建布尔掩码,并在boolean indexing中使用掩码和过滤器:

df_filter = df_exam[df_exam["sex"].eq("F").groupby(df_exam["date"]).transform('any')]

或者也不错的替代方案,如果更好,则取决于数据,例如 transform - 按条件获取所有 dates 并在 boolean indexing 中使用 Series.isin 过滤:

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

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

【讨论】:

    【解决方案2】:

    测试是验证算法是否更有效的确定方法;但是,乍一看,如果可以避免匿名函数(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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 2020-09-28
      • 2017-10-04
      • 2021-07-22
      • 2021-05-06
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多