Hofbr
Hofbr

Reputation: 1010

How to iterate through rows and % weight of groups of rows based on conditional

I have a dataframe that looks like this.

The only thing I don't have is the '% of Weight'. I need it to take the weight of every return from its respective total (whichever total immediately proceeds it.

The structure is not consistent. Sometimes there can be 3 categories that get totaled for an account for a particular month and sometimes there can be 4 or 5.

I need to iterate through 'Monthly MV column' and find the weight of each category for its months total.

Currently looks like this:

Return Date    Account    Category    Monthly MV    
 7/31/2003      abcdef     BOND        1.00          
 7/31/2003      abcdef     CASH        0.50          
 7/31/2003      abcdef     EQUITY      1.50         
 7/31/2003      abcdef     TOTAL       3.00          
 8/30/2003      abcdef     ALT         1.00             
 8/30/2003      abcdef     BOND        1.00         
 8/30/2003      abcdef     CASH        0.25         
 8/30/2003      abcdef     EQUITY      2.50         
 8/30/2003      abcdef     REAL        0.25         
 8/30/2003      abcdef     TOTAL       5.00          

It should look like this:

Return Date    Account    Category    Monthly MV    % of Weight
 7/31/2003      abcdef     BOND        1.00          0.33333
 7/31/2003      abcdef     CASH        0.50          0.1667
 7/31/2003      abcdef     EQUITY      1.50          0.5
 7/31/2003      abcdef     TOTAL       3.00          1.00
 8/30/2003      abcdef     ALT         1.00          0.20     
 8/30/2003      abcdef     BOND        1.00          0.20
 8/30/2003      abcdef     CASH        0.25          0.05
 8/30/2003      abcdef     EQUITY      2.50          0.5
 8/30/2003      abcdef     REAL        0.25          0.05
 8/30/2003      abcdef     TOTAL       5.00          1.00

Upvotes: 1

Views: 28

Answers (1)

Quang Hoang
Quang Hoang

Reputation: 150735

IIUC, you can back fill the TOTAL rows and simply divide:

df['% of Weight'] = df['Monthly MV'].div(df['Monthly MV']
                                         .where(df['Category'].eq('TOTAL'))
                                         .bfill()
                                        )

Output:

  Return Date Account Category  Monthly MV  % of Weight
0   7/31/2003  abcdef     BOND        1.00     0.333333
1   7/31/2003  abcdef     CASH        0.50     0.166667
2   7/31/2003  abcdef   EQUITY        1.50     0.500000
3   7/31/2003  abcdef    TOTAL        3.00     1.000000
4   8/30/2003  abcdef      ALT        1.00     0.200000
5   8/30/2003  abcdef     BOND        1.00     0.200000
6   8/30/2003  abcdef     CASH        0.25     0.050000
7   8/30/2003  abcdef   EQUITY        2.50     0.500000
8   8/30/2003  abcdef     REAL        0.25     0.050000
9   8/30/2003  abcdef    TOTAL        5.00     1.000000

Upvotes: 1

Related Questions