【问题标题】: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
【解决方案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。
【解决方案3】:
您可以将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