我有这个数据框:
mu_post
z c t
index a b
0 0.0 0.0 0.042824 0.051212
0.5 0.5 0.048293 0.058130
1.0 1.0 0.047267 0.074043
1 0.0 0.0 0.058205 0.054106
0.5 0.5 0.064153 0.063573
1.0 1.0 0.056918 0.059572
2 0.0 0.0 0.059032 0.052211
0.5 0.5 0.070616 0.066792
1.0 1.0 0.056892 0.045061
制作者:
import pandas as pd
df = pd.DataFrame({('mu_post', 'c'): {(0, 0.0, 0.0): 0.042824223871028126, (0, 0.5, 0.5): 0.04829260822563669, (0, 1.0, 1.0): 0.047267365970316805, (1, 0.0, 0.0): 0.05820509767743391, (1, 0.5, 0.5): 0.06415323721481726, (1, 1.0, 1.0): 0.0569177959009184, (2, 0.0, 0.0): 0.05903204294019807, (2, 0.5, 0.5): 0.07061613725719014, (2, 1.0, 1.0): 0.056892088025082874}, ('mu_post', 't'): {(0, 0.0, 0.0): 0.051212446939110846, (0, 0.5, 0.5): 0.058129980845875964, (0, 1.0, 1.0): 0.07404310411549644, (1, 0.0, 0.0): 0.05410577324029455, (1, 0.5, 0.5): 0.06357338131851693, (1, 1.0, 1.0): 0.0595723832219094, (2, 0.0, 0.0): 0.05221119083827467, (2, 0.5, 0.5): 0.06679207329135116, (2, 1.0, 1.0): 0.04506069626935631}})
我想补充
odds
。
def odds(p):
return p / (1-p)
我可以这样分配:
df.assign(
odds_c=lambda x: odds(x[('mu_post', 'c')]),
odds_t=lambda x: odds(x[('mu_post', 't')]),
)
mu_post odds_c odds_t
c t
0 0.0 0.0 0.042824 0.051212 0.044740 0.053977
0.5 0.5 0.048293 0.058130 0.050743 0.061718
1.0 1.0 0.047267 0.074043 0.049612 0.079964
1 0.0 0.0 0.058205 0.054106 0.061802 0.057201
0.5 0.5 0.064153 0.063573 0.068551 0.067889
1.0 1.0 0.056918 0.059572 0.060353 0.063346
2 0.0 0.0 0.059032 0.052211 0.062735 0.055087
0.5 0.5 0.070616 0.066792 0.075982 0.071573
1.0 1.0 0.056892 0.045061 0.060324 0.047187
但我真正想要的是 MultiIndex 列
[(mu_post, c), (mu_post, t), (odds, c), (odds, t)]
如果可能的话,我想一起使用管道/应用/分配风格的链接方法。
您可以加入/申请/重命名:
In [188]: df.join(df.apply(odds).rename(columns={"mu_post": "odds"}))
Out[188]:
mu_post odds
c t c t
0 0.0 0.0 0.042824 0.051212 0.044740 0.053977
0.5 0.5 0.048293 0.058130 0.050743 0.061718
1.0 1.0 0.047267 0.074043 0.049612 0.079964
1 0.0 0.0 0.058205 0.054106 0.061802 0.057201
0.5 0.5 0.064153 0.063573 0.068551 0.067889
1.0 1.0 0.056918 0.059572 0.060353 0.063346
2 0.0 0.0 0.059032 0.052211 0.062735 0.055087
0.5 0.5 0.070616 0.066792 0.075982 0.071573
1.0 1.0 0.056892 0.045061 0.060324 0.047187
您可以使用
MultiIndex
再次创建列,然后将其分配回来
dd=df.assign(
odds_c=lambda x: odds(x[('mu_post', 'c')]),
odds_t=lambda x: odds(x[('mu_post', 't')]),
)
dd.columns=pd.MultiIndex.from_product([['mu_post','odd'],['c','t']])
dd
Out[506]:
mu_post odd
c t c t
0 0.0 0.0 0.042824 0.051212 0.044740 0.053977
0.5 0.5 0.048293 0.058130 0.050743 0.061718
1.0 1.0 0.047267 0.074043 0.049612 0.079964
1 0.0 0.0 0.058205 0.054106 0.061802 0.057201
0.5 0.5 0.064153 0.063573 0.068551 0.067889
1.0 1.0 0.056918 0.059572 0.060353 0.063346
2 0.0 0.0 0.059032 0.052211 0.062735 0.055087
0.5 0.5 0.070616 0.066792 0.075982 0.071573
1.0 1.0 0.056892 0.045061 0.060324 0.047187
Pandas 是围绕索引和索引对齐构建的。如果你不能轻松地做某件事,很可能你没有以正确的方式索引数据(这是我必须不断提醒自己的事情)。这是 PyData 的 James Powell 就此问题所做的精彩演讲(事实上,我现在要再看一遍)。
让我们应用这种想法 - 当我们按元素应用函数时,我们可以重塑它,以便我们在 MultiIndex 上有一个包含许多行的单列。
df.stack()
Out[3]:
mu_post
0 0.0 0.0 c 0.042824
t 0.051212
0.5 0.5 c 0.048293
t 0.058130
1.0 1.0 c 0.047267
t 0.074043
1 0.0 0.0 c 0.058205
t 0.054106
0.5 0.5 c 0.064153
t 0.063573
...
现在分配新列很容易:
df.stack().assign(odds=lambda df: df.map(odds))
Out[4]:
mu_post odds
0 0.0 0.0 c 0.042824 0.044740
t 0.051212 0.053977
0.5 0.5 c 0.048293 0.050743
...
并重塑:
df.stack().assign(odds=lambda df: df.map(odds)).unstack()
Out[5]:
mu_post odds
c t c t
0 0.0 0.0 0.042824 0.051212 0.044740 0.053977
0.5 0.5 0.048293 0.058130 0.050743 0.061718
1.0 1.0 0.047267 0.074043 0.049612 0.079964
1 0.0 0.0 0.058205 0.054106 0.061802 0.057201
0.5 0.5 0.064153 0.063573 0.068551 0.067889
1.0 1.0 0.056918 0.059572 0.060353 0.063346
2 0.0 0.0 0.059032 0.052211 0.062735 0.055087
0.5 0.5 0.070616 0.066792 0.075982 0.071573
1.0 1.0 0.056892 0.045061 0.060324 0.047187
我们可以看到列索引被保留,并在列级别 0 添加了
odds
。