Suppose I have a dataframe with a multiindex columns object where the first level defines some category and the second level defines a component of a formula. Consider the dataframe df
np.random.seed([3,1415])
mux = pd.MultiIndex.from_product([list('XYZ'), list('kap'), ])
df = pd.DataFrame(np.random.randint(1, 5, size=(2, 9)), columns=mux)
df
X Y Z
k a p k a p k a p
0 1 4 3 4 3 3 4 3 4
1 2 4 2 3 4 4 1 4 3
I want to calculate the the formula k * a ** p for each of X, Y, and Z
I could assign to a separate dataframe
x = df.X
x.eval('k * a ** p')
0 64
1 32
dtype: int64
But how do I get this for X, Y, and Z all at once.
The final result should look like:
X Y Z
0 64 108 324
1 32 768 64
1). One way would be groupby on level
In [1841]: df.groupby(level=0, axis=1).apply(lambda x: x[x.name].eval('k*a**p'))
Out[1841]:
X Y Z
0 64 108 324
1 32 768 64
2). Another, loop by levels.
In [1818]: pd.DataFrame({c: df[c].eval('k*a**p') for c in df.columns.levels[0]})
Out[1818]:
X Y Z
0 64 108 324
1 32 768 64
Solution without eval:
d = {c: df[c].assign(A=lambda x: x.k*x.a**x.p)['A'] for c in df.columns.levels[0]}
df1 = pd.DataFrame(d)
print (df1)
X Y Z
0 64 108 324
1 32 768 64
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