I'm a bit new to Python and Pandas and I do not understand how to stack data based on part of the column name.
My data looks like below: (part of sample data)
| ID | Region | Rep | Item_Loop1 | Units_A_Loop1 | Type_col_X_Loop1 | Unit_Cost_Type_New_Loop1xyz | Total_Loop1ABCD | Item_Loop2 | Units_A_Loop2 | Type_col_X_Loop2 | Unit_Cost_Type_New_Loop2xyz | Total_Loop2ABCD |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Central | Andrews | Pencil | 75 | A | 1,99 | 149,25 | Pencil | 66 | Q | 1,99 | 131,34 |
| 4 | Central | Jardine | Pen Set | 50 | C | 4,99 | 249,5 | Pen Set | 50 | V | 4,99 | 249,5 |
| 5 | East | Jones | Pencil | 95 | B | 1,99 | 189,05 | Binder | 60 | A | 4,99 | 299,4 |
| 6 | Central | Kivell | Binder | 50 | X | 19,99 | 999,5 | Pen Set | 96 | G | 4,99 | 479,04 |
Except first 3 columns (ID, Region, Rep) all other columns contain the same substring "Loop" with number of loop, e.g. loop1, loop2, loop3 --> Item_Loop1, Item_Loop2, Item_Loop3
I need to change this data to the one stacked by ID. So for example for ID = 1 there will be 2 additional rows for each loop:
| ID | Region | Rep | Loop | Item_ | Units_A_ | Type_col_X_ | Unit_Cost_Type_New_xyz | Total_ABCD |
|---|---|---|---|---|---|---|---|---|
| 1 | Central | Andrews | Loop1 | Pencil | 75 | A | 1,99 | 149,25 |
| 1 | Central | Andrews | Loop2 | Pencil | 66 | Q | 1,99 | 131,34 |
| 1 | Central | Andrews | Loop3 | Pencil | 14 | X | 1,29 | 18,06 |
| 4 | Central | Jardine | Loop1 | Pen Set | 50 | C | 4,99 | 249,5 |
| 4 | Central | Jardine | Loop2 | Pen Set | 50 | V | 4,99 | 249,5 |
| 4 | Central | Jardine | Loop3 | Binder | 11 | Y | 4,99 | 54,89 |
| 5 | East | Jones | Loop1 | Pencil | 95 | B | 1,99 | 189,05 |
| 5 | East | Jones | Loop2 | Binder | 60 | A | 4,99 | 299,4 |
| 5 | East | Jones | Loop3 | Pencil | 35 | Q | 4,99 | 174,65 |
| 5 | East | Jones | Loop4 | Pen Set | 16 | A | 15,99 | 255,84 |
| 5 | East | Jones | Loop5 | Binder | 60 | G | 8,99 | 539,4 |
What I've tried doing us to split columns by _ and stacking it with 'loop'. The problem that I found was that my columns have multiple _ in it and after 'loopX' there is additional text. I've tried slicing column names with rfind/slice, but I couldn't execute reasonable results.
My general idea was more or less:
df.columns = df.columns.str.split('_', expand=True)
#I've tried to use rfind and slicing column name to -> find index of last '_' and get 5 next characters, but I couldn't execute it without errors
df = df.stack(dropna=False).rename_axis(['ID','Region','Rep','Loop']).reset_index()
I'm also not sure why in preview tables look good, but when posted it's not :(