如何防止Groupby超越指数?

人气:49 发布:2023-01-03 标签: python pandas multi-index

问题描述

假设您有以下半MultiIndex object

import pandas as pd
df = pd.DataFrame({
    'c': {
        ('r', 'r1'): 1.,
        ('r', 'r2'): 2.,
    },
})
print(df)
#       c
# r r1  1
#   r2  2

让我们重点关注分层索引,即垂直索引。首先,请注意,正如预期的那样,我们拥有

>>> df.index.__class__.__name__
'MultiIndex'

重点是pandas.DataFrame.groupby可能-classdf.index取决于最终的级数是否为1。

>>> dfg = df.groupby(axis=0, level=0).sum()
>>> dfg.index.__class__.__name__
'Index'

防止/纠正此类行为的最干净方法是什么?目前,我同意

>>> dfg.index = pd.Index((c,) for c in dfg.index)  # Doing so is equivalent to using `pd.MultiIndex.from_tuples`
>>> dfg.index.__class__.__name__
'MultiIndex'

为什么?查看评论:没有XY问题...

假设您要将求和的值传播到更低的级别。SO上提出的解决方案都不适合我。可读性不足和/或隐藏了有趣的临时计算。原来,在源和处理MultiIndex实例时,执行此类传播变得相当容易。

>>> df_            = df.copy()  # copy for the sake of illustration
>>> df_.iloc[:, :] = dfg  # Actually equivalent to `df_.update(dfg)`
>>> df_
      c
r r1  3
  r2  3
# whereas without correction:
#        c
# r r1 nan
#   r2 nan

NB:此方法适用于所有dfg.index.nlevels

推荐答案

尝试使用pd.DataFrame.align

df.align(dfg, level=0)

输出:

(        c
 r r1  1.0
   r2  2.0,
         c
 r r1  3.0
   r2  3.0)

注意:每个数据帧具有相同索引的元组。

然后,

 pd.concat(list(df.align(dfg, level=0)), axis=1)

然后您可以获得连接的数据帧,如下所示:

        c    c
r r1  1.0  3.0
  r2  2.0  3.0

21