【问题标题】:pandas - how to create multiple columns in groupby with conditional?pandas - 如何在有条件的 groupby 中创建多个列?
【发布时间】:2018-11-21 14:15:01
【问题描述】:

我需要对数据框进行分组,但我需要创建两列,一列是简单计数,另一列是有条件的计数,如示例中所示:

qtd_ok 列仅计算“OK”的那些

我试过这个,但我不知道如何在同一个groupby中添加总数:

df.groupby(['column1', 'column2', 'column3']).apply(lambda x : x['status'].sum() == 'OK')

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    首先使用assign 创建帮助器列A,然后通过agg 函数聚合sum 仅用于计数OK 值和size 用于计算每个组的所有值:

    df = (df.assign(A=(df['status']== 'OK'))
            .groupby(['column1', 'column2', 'column3'])['A']
            .agg([('qtd_ok','sum'),('qtd','size')])
            .astype(int)
            .reset_index())
    

    示例:

    df = pd.DataFrame({
            'column1':['a'] * 9,
            'column2':['a'] * 4 + ['b'] * 5,
            'column3':list('aaabaabbb'),
            'status':list('aabaaabba'),
    })
    
    print (df)
      column1 column2 column3 status
    0       a       a       a      a
    1       a       a       a      a
    2       a       a       a      b
    3       a       a       b      a
    4       a       b       a      a
    5       a       b       a      a
    6       a       b       b      b
    7       a       b       b      b
    8       a       b       b      a
    
    df = (df.assign(A=(df['status']== 'a'))
            .groupby(['column1', 'column2', 'column3'])['A']
            .agg([('qtd_ok','sum'),('qtd','size')])
            .astype(int)
            .reset_index())
    print (df)
      column1 column2 column3  qtd_ok  qtd
    0       a       a       a       2    3
    1       a       a       b       1    1
    2       a       b       a       2    2
    3       a       b       b       1    3
    

    【讨论】:

    • 很高兴知道,+1
    【解决方案2】:

    将 groupby 与 lambda 一起计数只是一个想法,可以进一步增强..

    >>> df
      colum1    colum2    colum3 status
    0  unit1  section1  content1     OK
    1  unit1  section1  content1     OK
    2  unit1  section1  content1  error
    3  unit1  section1  content2     OK
    4  unit1  section2  content1     OK
    5  unit1  section2  content1     OK
    6  unit1  section2  content2  error
    7  unit1  section2  content2  error
    8  unit1  section2  content2     OK
    

    使用 groupby 和 lambda..

     >>> df.groupby(['colum1','colum2', 'colum3'])['status'].apply(lambda x: x[x.str.contains('OK', case=False)].count()).reset_index()
      colum1    colum2    colum3  status
    0  unit1  section1  content1       2
    1  unit1  section1  content2       1
    2  unit1  section2  content1       2
    3  unit1  section2  content2       1
    

    也可以使用case=False 忽略ok。

    【讨论】:

    • OP 期望 GroupBy 的两个输出列。
    【解决方案3】:

    pd.crosstab

    您可以将pd.crosstab 与margins=True 一起使用:

    # data from @jezrael
    
    list_of_lists = df.iloc[:, :-1].values.T.tolist()
    condition = df['status'].eq('a')
    
    res = pd.crosstab(list_of_lists, condition, margins=True)\
            .drop('All', level=0).reset_index()
    
    print(res)
    
    status column1 column2 column3  False  True  All
    0            a       a       a      1     2    3
    1            a       a       b      0     1    1
    2            a       b       a      0     2    2
    3            a       b       b      2     1    3
    

    【讨论】:

    • 另一个不错的解决方案 +1
    猜你喜欢
    • 1970-01-01
    • 2021-06-11
    • 2022-01-23
    • 2021-04-06
    • 2022-11-23
    • 1970-01-01
    • 2017-12-19
    • 2019-04-04
    • 1970-01-01
    相关资源
    最近更新 更多