Reputation: 1499
I'm trying to use Pandas and groupby to calculate the ratio of two columns. In the example below I want to calculate the ratio of staff Status per Department (Number of Status in Department/Total Number of Employees per Department). For example the Sales department has a total of 3 Employees and the number of staff that have Employee Status is 2 which gives the ratio of 2/3, 66.67%. I managed to hack my way through to get this but there must be a more elegant and simple way to do this. How can I get the desired output below more efficiently?
Original DataFrame:
Department Name Status
0 Sales John Employee
1 Sales Steve Employee
2 Sales Sara Contractor
3 Finance Allen Contractor
4 Marketing Robert Employee
5 Marketing Lacy Contractor
Code:
mydict ={
'Name': ['John', 'Steve', 'Sara', 'Allen', 'Robert', 'Lacy'],
'Department': ['Sales', 'Sales', 'Sales', 'Finance', 'Marketing', 'Marketing'],
'Status': ['Employee', 'Employee', 'Contractor', 'Contractor', 'Employee', 'Contractor']
}
df = pd.DataFrame(mydict)
# Create column with total number of staff Status per Department
df['total_dept'] = df.groupby(['Department'])['Name'].transform('count')
print(df)
print('\n')
# Crate column with Status ratio per department
for k, v, in df.iterrows():
df.loc[k, 'Status_Ratio'] = (df.groupby(['Department', 'Status']).count().xs(v['Status'], level=1)['total_dept'][v['Department']]/v['total_dept']) *100
print(df)
print('\n')
# Final Groupby with Status Ratio. Size NOT needed
print(df.groupby(['Department', 'Status', 'Status_Ratio']).size())
Desired Output:
Department Status Status_Ratio
Finance Contractor 100.00
Marketing Contractor 50.00
Employee 50.00
Sales Contractor 33.33
Employee 66.67
Upvotes: 2
Views: 4009
Reputation: 13387
Try (with the original df
):
df.groupby("Department")["Status"].value_counts(normalize=True).mul(100)
Outputs:
Department Status
Finance Contractor 100.000000
Marketing Contractor 50.000000
Employee 50.000000
Sales Employee 66.666667
Contractor 33.333333
Name: Status, dtype: float64
Upvotes: 5