Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate an expression based on names in the second level of a mult-index column

Tags:

python

pandas

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
like image 989
piRSquared Avatar asked May 18 '26 09:05

piRSquared


2 Answers

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
like image 111
Zero Avatar answered May 20 '26 23:05

Zero


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
like image 24
jezrael Avatar answered May 20 '26 23:05

jezrael