Calculate shares of parent total in Pandas DataFrame

Viewed 894

I was wondering if there is any better way to calculate the shares of parent total in Pandas, compared to the one below: many thanks for your help!

raw_data = {'product': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C'],
        'revenue': [10,20,20,0,50,50,0,0,30]}
df = pd.DataFrame(raw_data, columns = ['product', 'revenue'])

unique_values = df['product'].unique()
L = pd.DataFrame ()

for value in unique_values:
    small_df = df[df['product']==value]
    small_df['shares'] = small_df['revenue']/small_df['revenue'].sum()
    L = L.append(small_df, ignore_index=True)

print(L)
3 Answers

Try this:

df['shares'] = df.groupby('product')['revenue'].apply(lambda x: x/ x.sum())

In [898]: df
Out[898]: 
  product  revenue  shares
0       A       10     0.2
1       A       20     0.4
2       A       20     0.4
3       B        0     0.0
4       B       50     0.5
5       B       50     0.5
6       C        0     0.0
7       C        0     0.0
8       C       30     1.0
(df.set_index("product") / df.groupby('product').sum()).reset_index()

  product  revenue
0       A      0.2
1       A      0.4
2       A      0.4
3       B      0.0
4       B      0.5
5       B      0.5
6       C      0.0
7       C      0.0
8       C      1.0

You can divide revenue by GroupBy + transform with sum:

df['shares'] = df['revenue'] / df.groupby('product')['revenue'].transform('sum')

print(df)

  product  revenue  shares
0       A       10     0.2
1       A       20     0.4
2       A       20     0.4
3       B        0     0.0
4       B       50     0.5
5       B       50     0.5
6       C        0     0.0
7       C        0     0.0
8       C       30     1.0
Related