根据熊猫中的条件进行分组和过滤

时间:2021-04-11 09:33:39

标签: python pandas database dataframe group-by

如果满足某一列的条件,我想删除整个组,(不要关注列 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

例如,如果“访问”包含字符串“cream”,则所有主题 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)])

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

根据条件,如果组包含“cream”或“not”,使用变换将 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]

答案 2 :(得分:0)

您可以使用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

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

答案 3 :(得分:0)

您可以通过首先创建检查 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