Sorry for the messy title, I didn't know how to phrase this question well.
Let's say I have a table in which the first three columns are foo bar and baz. Then there are some number of arbitrary columns after. I want to manipulate the table such that these arbitrary columns are all collapsed under on column, called num.
An example makes this clearer
foo, bar, baz, 100, 101, 102, 103, 104,
1,   1,   1,  10,  11,  12,  13,  14,
1,   1,   2,  15,  16,  17,  18,  19,
1,   2,   1,  20,  21,  22,  23,  24,
This input should transpose to:
num, foo, bar, baz, value,
100,   1,    1,  1,    10,
100,   1,    1,  2,    15,
100,   1,    2,  1,    20,
101,   1,    1,  1,    11,
101,   1,    1,  2,    16,
101,   1,    2,  1,    21,
102,   1,    1,  1,    12,
102,   1,    1,  2,    17,
102,   1,    2,  1,    22,
...
I wrote a custom Python solution that does this. It wasn't hard, but I feel like this is reinventing the wheel.
Is there a way to accomplish this with a library like pandas or some other table manipulation module?
Using pandas.melt:
res = pd.melt(df, id_vars=['foo', 'bar', 'baz'])
print(res)
    foo  bar  baz variable  value
0     1    1    1      100     10
1     1    1    2      100     15
2     1    2    1      100     20
3     1    1    1      101     11
4     1    1    2      101     16
5     1    2    1      101     21
6     1    1    1      102     12
7     1    1    2      102     17
8     1    2    1      102     22
9     1    1    1      103     13
10    1    1    2      103     18
11    1    2    1      103     23
12    1    1    1      104     14
13    1    1    2      104     19
14    1    2    1      104     24
                        cols = np.concatenate([['num'], df.columns[:3], ['value']])
pd.DataFrame([
    [a, b, c, d, e]
    for b, c, d, *x in df.values
    for a, e in zip(df.columns[3:], x)
]).set_axis(cols, axis=1, inplace=False).sort_values('num')
    num  foo  bar  baz  value
0   100    1    1    1     10
5   100    1    1    2     15
10  100    1    2    1     20
1   101    1    1    1     11
6   101    1    1    2     16
11  101    1    2    1     21
2   102    1    1    1     12
7   102    1    1    2     17
12  102    1    2    1     22
3   103    1    1    1     13
8   103    1    1    2     18
13  103    1    2    1     23
4   104    1    1    1     14
9   104    1    1    2     19
14  104    1    2    1     24
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With