Fairly specific problem here - Below is the code i'm currently using that has a two inputs:
- A reference dictionary (ref_dict in the code below) that has a single number as the keys, and the values being lists of 2-5 numbers (right now this is static in the file for building purposes, will build it out to pull from a file instead eventually)
- A pandas df (right now being read from a csv for building purposes, but when implemented into production will be given an actual dataframe directly), that looks something like this:
| week | day | country | contsize | code | total |
|---|---|---|---|---|---|
| W1 | Tu | US | M | 1 | 8 |
| W1 | Tu | CA | M | 2 | 4 |
| W1 | Tu | US | M | 10 | 13 |
| W1 | Tu | US | M | 20 | 2 |
| W1 | Tu | CA | M | 20 | 16 |
| W1 | W | US | M | 30 | 9 |
What i'm trying to do is:
- Iterate through the rows of the df, look into the 'code' column and see if it matches any of the keys in the dictionary
- If it matches any keys in the dictionary, I want to remove the 'total' and add it to the list of values related to the key in the dictionary ONLY if the other columns match. (so for example code 1 should give its total to to codes 10, 20, 30, code 2 should give it to 10, 20, etc. assuming all other columns are constant)
- So in the table above example, the first row would take the 8, add it to row 3 and 4 (as code 10 and 20 are within the reference dictionary), but not 5 because the country is different, and not 6 because the day is different
- the second row would take the 4 and would only add to row 5 (as code 20 is in the reference dictionary) but not any other as the country is different
- Delete row 1 and 2
Expected output:
| week | day | country | contsize | code | total |
|---|---|---|---|---|---|
| W1 | Tu | US | M | 10 | 21 |
| W1 | Tu | US | M | 20 | 10 |
| W1 | Tu | CA | M | 20 | 20 |
| W1 | W | US | M | 30 | 9 |
As of now with my below code, it is currently running through, adding totals and deleting the appropriate rows, except the totals are increasing by all of the values rather than the ones outlined in the reference dictionary.
| Code - 10 | Week 1 - Monday |
|---|---|
| Before | 142 |
| Expected | 199 |
| Actual After | 221 |
| Difference | 22 |
| Code 1 | 26 |
| Code 2 | 26 |
| Code 3 | 22 |
| Code 4 | 5 |
With expected being 142 + 26 + 26 + 5 = 199 (Starting number + codes 1, 2, 4 as these 3 are the ones that should impact code 10) and difference being 221-199 = 22 (which is equal to #3 in the dict). I confirmed this across 2 separate weeks looking at all 5 possible days in the day column, its increasing by the exact amount.
Any tips?
import pandas as pd
def ref_dict():
# Will update to pull from file instead
ref_dict = {
1: ['10', '20', '30'],
2: ['10', '20'],
3: ['20', '30'],
4: ['10', '30']
}
return ref_dict
def unbundle(ref_dict):
# Will update this to dataframe from IMS
df = pd.read_csv('test.csv')
df['remove'] = df.code.isin(ref_dict)
for _, row in df[df.remove].iterrows():
if row.code not in ref_dict:
continue
is_match = (df.week == row.week) & (df.day == row.day) & (df.country == row.country) & (df.contsize == row.contsize)
df.loc[~df.remove & is_match, 'total'] += row.total
df = df[~df.remove].drop(columns='remove')
return df
def bundles():
ref_dict = ref_dict()
new_totals = unbundle(ref_dict)
new_totals.to_csv('final.csv')
bundles()