在 pandas 多重索引中分配列

问题描述 投票:0回答:3

我有这个数据框:

                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)]

如果可能的话,我想一起使用管道/应用/分配风格的链接方法。

python pandas multi-index
3个回答
3
投票

您可以加入/申请/重命名:

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

2
投票

您可以使用

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

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.