假设我有一个带有multiindex列对象的数据帧,其中第一级定义了某个类别,第二级定义了公式的组件。考虑数据框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
我想为每个k * a ** p
,X
和Y
Z
我可以分配一个单独的数据框
x = df.X
x.eval('k * a ** p')
0 64
1 32
dtype: int64
但是如何同时为X
,Y
和Z
提供此功能。
最终结果如下:
X Y Z
0 64 108 324
1 32 768 64
答案 0 :(得分:3)
1)。 groupby
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)。另一个,按级别循环。
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
答案 1 :(得分:2)
没有评估的解决方案:
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
答案 2 :(得分:1)
选项1
df.stack(0).eval('k * a ** p').unstack()
X Y Z
0 64 108 324
1 32 768 64
选项2
df.swaplevel(0, 1, 1).pipe(lambda d: d.k * d.a ** d.p)
X Y Z
0 64 108 324
1 32 768 64
答案 3 :(得分:1)
有点难看,但涉及对列进行排序,然后调用.mul
和.pow
。
df2 = df.sort_index(level=[0, 1], axis=1)
v = df2.loc[:, (slice(None), 'a')]\
.pow(df2.loc[:, (slice(None), 'p')].values, 1)
out = df2.loc[:, (slice(None), 'k')].mul(v.values, 1)
print(out)
X Y Z
k k k
0 64 108 324
1 32 768 64