Используйте groupby
с GroupBy.size
для подсчета всех данных, затем для подсчета по категориям нужно поворачиваться - с GroupBy.size
и unstack
, crosstab
или pivot_table
:
df1 = df.groupby('type').size().reset_index(name='count')
df2 = (df.groupby(['type', 'success']).size().unstack(fill_value=0)
.rename(columns={True:'numOfSuccess', False:'numOfFails'}))
Альтернатива для df2
:
df2 = pd.crosstab(df['type'], df['success'])
.rename(columns={True:'numOfSuccess', False:'numOfFails'}))
Или:
df2 = (df.pivot_table(index='type', columns='success', fill_value=0, aggfunc='size')
.rename(columns={True:'numOfSuccess', False:'numOfFails'}))
df_new = df1.join(df2, on='type')
print (df_new)
type count numOfFails numOfSuccess
0 A 2 1 1
1 B 1 1 0
2 C 1 0 1
Еще одним решением является использование параметра margins
в crosstab
и удаление последней строки путем индексации с помощью iloc
:
df = (pd.crosstab(df['type'], df['success'], margins=True)
.rename(columns={True:'numOfSuccess', False:'numOfFails', 'All':'count'})
.iloc[:-1]
.reset_index()
.rename_axis(None, axis=1))
print (df)
type numOfFails numOfSuccess count
0 A 1 1 2
1 B 1 0 1
2 C 0 1 1
РЕДАКТИРОВАТЬ: Если возможно True
или False
не существует, добавьте reindex
для добавления отсутствующего столбца:
print (df)
type success
0 A True
1 B True
2 A True
3 C True
df1 = df.groupby('type').size().reset_index(name='count')
df2 = (df.groupby(['type', 'success']).size().unstack(fill_value=0)
.reindex(columns=[True, False], fill_value=0)
.rename(columns={True:'numOfSuccess', False:'numOfFails'}))
df_new = df1.join(df2, on='type')
print (df_new)
type count numOfSuccess numOfFails
0 A 2 2 0
1 B 1 1 0
2 C 1 1 0