【问题标题】:Group by and filter based on a condition in pandas根据熊猫中的条件分组和过滤
【发布时间】:2021-07-06 15:37:15
【问题描述】:

如果满足某一列的条件,我想删除整个组,(不要关注列 X1 和 X2):

 Subject  Visit           X1      X2
   A       aaa          1647143  1672244
   A       creamy       1672244  1689707
   A       bbb          1689707  1713090
   B       yyy          1735352  1760283
   B       ice cream    1760283  1788062
   C       foo          1788062  1789885
   C       doo          1789885  1790728

例如,如果“访问”包含字符串“奶油”,所有主题 A 和主题 B 记录将被删除,结果将是:

Subject  Visit      X1      X2

 C       foo    1788062  1789885
 C       doo    1789885  1790728

我试过了:并没有删除整个组记录

df.groupby(by=['Subject']).apply(lambda d: d[~d['Visit'].str.contains('cream',flags=re.I, regex=True)])

【问题讨论】:

    标签: python pandas database dataframe group-by


    【解决方案1】:

    Groupby 然后检查Visit 列是否每个组都包含cream 字符串。

    def move_group(group):
        if not any(group['Visit'].str.contains('cream')):
            return group
    
    df_ = df.groupby('Subject').apply(move_group).dropna()
    
    # print(df_)
    
      Subject Visit         X1         X2
    5       C   foo  1788062.0  1789885.0
    6       C   doo  1789885.0  1790728.0
    

    【讨论】:

      【解决方案2】:

      使用转换将True/False 分配给group 的元素,具体取决于组是否包含“奶油”或“不”。然后删除具有False 值的行。

      mask = (df1.groupby('Subject')['Visit']
              .transform(lambda d: np.any(
                    d.str.contains('cream', flags = re.I, regex = True)))
              )
      df = df[~mask]
      

      【讨论】:

        【解决方案3】:

        你可以使用GroupBy.filter:

        df.groupby("Subject").filter(lambda gr: ~gr.Visit.str.contains("cream").any())
        

        得到

          Subject Visit       X1       X2
        5       C   foo  1788062  1789885
        6       C   doo  1789885  1790728
        

        我们过滤“在Visit 列中保留不 (~) 包含 (str.contains) 任何 (any) "cream" 的组”。

        【讨论】:

          【解决方案4】:

          您可以先创建检查cream 是否存在的列,然后使用transform 进行过滤,但在布尔值的总和上进行过滤:

          (df
          .assign(cream = df.Visit.str.contains("cream"))
          .loc[lambda df: df.groupby("Subject")
                            .cream
                            .transform("sum")==0, 
               df.columns]
          )
          Out[14]: 
            Subject Visit       X1       X2
          5       C   foo  1788062  1789885
          6       C   doo  1789885  1790728
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-27
            • 2017-11-30
            • 2022-01-25
            • 2020-09-04
            • 2017-11-20
            • 1970-01-01
            相关资源
            最近更新 更多