【问题标题】:How to prevent groupby from surclassing index?如何防止groupby超类索引?
【发布时间】:2021-08-29 08:37:38
【问题描述】:

假设你有以下半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 可能sur-class df.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'

为什么?查看 cmets:没有 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

注意:这种方法对所有dfg.index.nlevels都有效。

【问题讨论】:

  • 请问您的最终目标是什么?是否将此总数附加到原始数据框中?
  • 这似乎有点在xy 方向。您在轴 0 上的空级别 1 中寻找什么?
  • 还有反对transform:df.groupby(axis=0, level=0).transform('sum')的理由吗?
  • @HenryEcker 实际上,~.sum 的结果可能会经历一些代价高昂的调整,这些调整是要避免重复的。特别是~.transform,它基本上是作为for循环实现的。此外,出于多种原因,dfg 引起了人们的首要兴趣。
  • @ScottBoston 不。我的最终目标是在数百万行的较低级别传播dfg 的(经过成本调整的)值,同时在其他独立计算中也使用dfg(其中超类化不是问题)。

标签: python pandas multi-index


【解决方案1】:

尝试使用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

【讨论】:

  • 与我的相反,您的方法不能推广到 dfg.index.nlvels > 1 案例(提高 TypeError: Join on level between two MultiIndex objects is ambiguous),正如我在写 [...] 时所概述的那样,取决于是否最终级别数为 1。
  • @keepAlive 点已被占用。我认为您有更好的解决方案来满足您的要求。
猜你喜欢
  • 2017-06-20
  • 2016-10-19
  • 2021-04-01
  • 2011-01-06
  • 1970-01-01
  • 2015-05-17
  • 1970-01-01
  • 2012-08-25
  • 1970-01-01
相关资源
最近更新 更多