熊猫-如何在有条件的groupby中创建多个列?

时间:2018-11-21 14:15:01

标签: python pandas dataframe pandas-groupby

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

enter image description here

qtd_ok列仅计算具有“确定”的那些

enter image description here

我尝试了此操作,但是我不知道如何在同一groupby中添加总数:

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

3 个答案:

答案 0 :(得分: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 :(得分:1)

pd.crosstab

您可以将pd.crosstabmargins=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

答案 2 :(得分:1)

只是一个想法,可以用lambda来对groupby计数,这可以进一步增强。

>>> 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的{​​{1}}用作忽略大小写。