#Loop through example dataset
for id in df['val_id']:
#total assigned value
df['tot_val'] = 0
#loop through facilities
for fac in df['fac_id']:
if df['product'].isin(['XL', 'CL', 'DL']).all():
df['row'] = min(df['our_val_amt'] - df['tot_val'], df['val_against'])
else:
df['row'] = 0
df['tot_val'] = df['tot_val'] + df['row']
df['row'] = df['row'] + 1
Sample to test val_against > val_amt change
# df = pd.DataFrame(data=[["compx","xx1","yy1",424,418,"XL"],["compx","xx1","yy2",424,134,"CL"],["compx","xx2","yy3",472,60,"DL"],["compx","xx2","yy4",472,104,"CL"], ["compx", "xx3", "yy5", 490, 50, "XL"], ["compx", "xx3", "yy6", 490, 500, "CL"], ["compx", "xx3", "yy7", 490, 200, "DL"], ["compx", "xx4", "yy8", 510, 200, "CL"], ["compx", "xx4", "yy9", 510, 300, "CL"], ["compx", "xx4", "yy10", 510, 50, "XL"]], columns=["name","val_id","fac_id","our_val_amt","val_against","product"])
I am trying to in Pandas double loop through the 'val_id' and 'fac_id' column and create a new field from the following conditions.
1.Within each 'val_id' loop if 'product' == 'CL' then min of 'val_against' and 'our_val_amt' e.g. min( val_against (134), our_val_amt (424)) therefore 'NEW FIELD' = 134. Also if the sum of NEW FIELD exceeds "our_val_amt", then subtract it from "our_val_amt". e.g. for val_id "xx4", (200 + 300 + 50) = 550 which exceeds our_val_amt=510, so NEW FILED = 550 - 510 = 10.
2.If product != 'CL' and is in the same 'val_id' group. The remainder to be subtracted from 'our_val_amt' to be inserted in 'NEW FIELD'. e.g 'our_val_amt' (424) - from step 1 (134) = 290. This inserted above 'NEW FIELD'.
3.Repeat steps for val_id xx2. NEW FIELD calculation for CL = 104 and XL = 472 - 104 = 368.
Dataset with computed fields labeled with **
| name | val_id | fac_id | our_val_amt | val_against | product | **row** | **totval**|**Field Want**
| compx | xx1 | yy1 | 424 | 418 | XL | 290 | 0 | 290
| compx | xx1 | yy2 | 424 | 134 | CL | 134 | 134 | 134
| compx | xx2 | yy3 | 472 | 60 | DL | 0 | 0 | 368
| compx | xx2 | yy4 | 472 | 104 | CL | 104 | 104 | 104
| compx | xx3 | yy5 | 490 | 50 | XL |
| compx | xx3 | yy6 | 490 | 500 | CL |
| compx | xx3 | yy7 | 490 | 200 | DL |
| compx | xx4 | yy8 | 510 | 200 | CL |
| compx | xx4 | yy9 | 510 | 300 | CL |
| compx | xx4 | yy10 | 510 | 50 | CL |
Expected Output
| name | val_id | fac_id | our_val_amt | val_against | product | new field |
| compx | xx1 | yy1 | 424 | 418 | XL | 290 |
| compx | xx1 | yy2 | 424 | 134 | CL | 134 |
| compx | xx2 | yy3 | 472 | 60 | DL | 368 |
| compx | xx2 | yy4 | 472 | 104 | CL | 104 |
| compx | xx3 | yy5 | 490 | 50 | XL | 0 |
| compx | xx3 | yy6 | 490 | 500 | CL | 490 |
| compx | xx3 | yy7 | 490 | 200 | DL | 0 |
| compx | xx4 | yy8 | 510 | 200 | CL | 200 |
| compx | xx4 | yy9 | 510 | 300 | CL | 300 |
| compx | xx4 | yy10 | 510 | 50 | CL | 10 |
The **row** and ** totval** are fields i created trying to create the field that i want with the logic above.
I've tried grouping the variables together and having the 'product' as columns but unfortunately i receive 6000+ columns and have no idea on how to compute the calculation for this scenario.
I've also attempted to loop through but received incorrect outputs / errors
error: Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()