Pandas层次化索引和计算

3

假设:

df = pd.DataFrame({"panum": ["PA1", "PA1", "PA1", "PA2", "PA2", "PA2"], 
                   "which": ["A", "A", "A", "B", "B", "B"],
                 "score": [88, 80, 90, 92, 95, 99]})

df.set_index(['panum', 'which'], inplace=True)
df

             score
panum which       
PA1   A         88
      A         80
      A         90
PA2   B         92
      B         95
      B         99

是否有可能编写一些代码,以在“which”中创建一个名为max的新索引条目,该条目将是该级别的最大值,因此它将创建两个新行,PA1,Max和PA2,Max?

更新

我已更正索引。上面的示例不是我想要的。

panmum  factor  score
PA1     init    90
        resub   94
        final   93
PA2     init    60
        resub   90
        final   88

在这种更好的情况下,我的问题是:“我想创建一个名为mean的新“panum”,它将有三行,(mean,init),(mean,resub),(mean,final)。”

伪代码类似于 df['mean'] = (df['pa1'] + df['pa2']) / 2

我知道这是一个不同的问题!

2个回答

4
你可以创建一个新的 DataFrame,其中包含最大值,并添加第二级别的 max,然后将其 append 到原始数据中,最后进行 sort_index 处理:
m = df.max(level=0).assign(max='max').set_index('max', append=True)
print (m)
           score
panum max       
PA1   max     90
PA2   max     99

df = df.append(m).sort_index()
print (df)
             score
panum which       
PA1   A         88
      A         80
      A         90
      max       90
PA2   B         92
      B         95
      B         99
      max       99

编辑答案:使用二级索引的 meanswaplevel 解决方案以正确对齐最终的 DataFrame

df = pd.DataFrame({"panum": ["PA1", "PA1", "PA1", "PA2", "PA2", "PA2"], 
                   "factor": ["init", "resub", "final"] * 2,
                   "score": [90, 94, 93, 60, 90, 88]})

df.set_index(['panum', 'factor'], inplace=True)
print (df)
              score
panum factor       
PA1   init       90
      resub      94
      final      93
PA2   init       60
      resub      90
      final      88

m = (df.mean(level=1)
        .assign(factor='mean')
        .set_index('factor', append=True)
        .swaplevel(0,1))
print (m)
               score
factor factor       
mean   init     75.0
       resub    92.0
       final    90.5

df = df.append(m)
print (df)
              score
panum factor       
PA1   init     90.0
      resub    94.0
      final    93.0
PA2   init     60.0
      resub    90.0
      final    88.0
mean  init     75.0
      resub    92.0
      final    90.5

1
这正是我一开始想的。 - piRSquared

2

使用 pd.concat 进行追加最大值。

pd.concat([
    d.append(d.max().rename((n, 'max')))
    for n, d in df.groupby('panum')
])

             score
panum which       
PA1   A         88
      A         80
      A         90
      max       90
PA2   B         92
      B         95
      B         99
      max       99

谢谢您提供的解决方案...这是人们使用分层索引的东西,还是我超出了它的预期用途? - pitosalas
这并不是太过于挑战极限。问题在于您没有唯一的索引。索引的预期用途是能够识别唯一位置。因此,添加一个最大值是完全可以的。但是,由于索引不是唯一的,我无法使用更传统的轴移方法。而且......这种类型的问题以前已经被问过多次了。 - piRSquared
谢谢@piRSquared。我没看到其他相同问题的例子。顺便说一下,我不明白你所说的“唯一索引”。每个panum / which对都是唯一的。 - pitosalas
现在的情况是,你有 ('PA2', 'B') 作为索引重复了三次。对于值 929599,分别出现一次。当我尝试运行 data.unstack() 时,它会尝试将 'which' 级别放入 columns 对象中。但是,由于它不是唯一的,因此 unstack 就会出错。 - piRSquared
当然,我会纠正上面的例子。 - pitosalas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接