错误无法处理 groupby 子句中的非唯一多索引是啥意思?

Posted

技术标签:

【中文标题】错误无法处理 groupby 子句中的非唯一多索引是啥意思?【英文标题】:What is the meaning of the error cannot handle a non-unique multi index in groupby clause?错误无法处理 groupby 子句中的非唯一多索引是什么意思? 【发布时间】:2016-07-03 22:04:14 【问题描述】:

我有一个具有三个索引级别的数据框,我希望计算一个值偏离平均值的程度。但是根据我的指数,我对不同的群体有不同的意思。这是我尝试过的:

In [4]: df['count'].groupby(level=[0,1,2]).apply(lambda x: x-np.mean(x))

但是,我收到了一个错误,我在下面插入了堆栈跟踪。我不确定为什么会出现这样的问题。


Exception                                 Traceback (most recent call last)
<ipython-input-4-678992689ff2> in <module>()
----> 1 df['count'].groupby(level=[0,1,2]).apply(lambda x: x-np.mean(x))

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\groupby.pyc in apply(self, func, *args, **kwargs)
    713         # ignore SettingWithCopy here in case the user mutates
    714         with option_context('mode.chained_assignment',None):
--> 715             return self._python_apply_general(f)
    716
    717     def _python_apply_general(self, f):

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\groupby.pyc in _python_apply_general(self, f)
    720
    721         return self._wrap_applied_output(keys, values,
--> 722                                          not_indexed_same=mutated)
    723
    724     def aggregate(self, func, *args, **kwargs):

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\groupby.pyc in _wrap_applied_output(self, keys, values, not_indexed_same)
   2520         if isinstance(values[0], (Series, dict)):
   2521             return self._concat_objects(keys, values,
-> 2522                                         not_indexed_same=not_indexed_same)
   2523         elif isinstance(values[0], DataFrame):
   2524             # possible that Series -> DataFrame by applied function

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\groupby.pyc in _concat_objects(self, keys, values, not_indexed_same)
   1258
   1259             if isinstance(result, Series):
-> 1260                 result = result.reindex(ax)
   1261             else:
   1262                 result = result.reindex_axis(ax, axis=self.axis)

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\series.pyc in reindex(self, index, **kwargs)
   2266     @Appender(generic._shared_docs['reindex'] % _shared_doc_kwargs)
   2267     def reindex(self, index=None, **kwargs):
-> 2268         return super(Series, self).reindex(index=index, **kwargs)
   2269
   2270     @Appender(generic._shared_docs['fillna'] % _shared_doc_kwargs)

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\generic.pyc in reindex(self, *args, **kwargs)
   1960         # perform the reindex on the axes
   1961         return self._reindex_axes(axes, level, limit, tolerance,
-> 1962                                   method, fill_value, copy).__finalize__(self)
   1963
   1964     def _reindex_axes(self, axes, level, limit, tolerance, method,

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\generic.pyc in _reindex_axes(self, axes, level, limit, tolerance, method, fil
l_value, copy)
   1974             new_index, indexer = ax.reindex(
   1975                 labels, level=level, limit=limit, tolerance=tolerance,
-> 1976                 method=method)
   1977
   1978             axis = self._get_axis_number(a)

C:\Users\bchandra\AppData\Local\Continuum\Anaconda2\lib\site-packages\pandas\core\index.pyc in reindex(self, target, method, level, limit, tolerance)
   5280                 else:
   5281                     raise Exception(
-> 5282                         "cannot handle a non-unique multi-index!")
   5283
   5284         if not isinstance(target, MultiIndex):

Exception: cannot handle a non-unique multi-index!

我的数据框看起来像这样:

                 Count
      Cat SubCat 
        1   2      7
        1   2      5
        1   3      4
        1   3      3
        4   5      2
        4   5      1
        4   7      0
        4   7     -1

为简单起见,假设我的索引是 2 级而不是 3 级。 我想做的是按(cat,Sub)分组,这意味着(类别,子类别)。

然后在我按 cat=1, sub=2 分组的第一种情况下,在这里找到所有组的平均值,即 7+5/2=6。那我想分别找7-6和5-6。

类似df.groupby(level=[0,1]).apply(lambda x: x-np.mean(x))

一些在我的电脑上显示错误的虚拟代码(Pandas 版本 0.17.1):

index=[]
[index.append(x) for y in range(25) for x in np.arange(2)]
subindex=[]
[subindex.append(10*x) for y in range(25) for x in np.arange(2)]
sample=pd.DataFrame('count':np.arange(2*25),'cat':index,'sub':subindex,'date':np.random.randint(2*25))
sample.set_index(['cat','sub'],inplace=True)
sample['count'].groupby(level=[0,1]).apply(lambda x: x-np.mean(x))

【问题讨论】:

您能否发布数据和代码来重现此错误是否也会产生相同的错误df['count'].groupby(level=[0,1,2]).head() 您的索引中有重复项,并且您的函数不适用于重复项。删除重复项(通过删除它们或向区分它们的索引添加一个新字段),你会没事的。 ***.com/questions/13035764/… @EdChum,它在运行该命令时没有显示错误。如果你想看,我已经发布了一些虚拟数据。 在您的示例输入数据上它适用于我:In [64]: df.groupby(level=[0,1]).apply(lambda x: x-np.mean(x)) df.groupby(level=[0,1]).apply(lambda x: x-np.mean(x)) Out[64]: Count Cat SubCat 1 2 1.0 2 -1.0 3 0.5 3 -0.5 4 5 0.5 5 -0.5 7 0.5 7 -0.5 它在 pandas 0.15.1 上也适用于我 【参考方案1】:

我在汇总数据时遇到了同样的错误。有很多列,我没有注意到其中一些是重复的列。在分组依据之前,请检查所有列名或使用函数删除分层索引中的重复项。

【讨论】:

【参考方案2】:

拥有一个多索引数据框,您可能没有注意到在级别 0、1 或 2 存在重复的列名。这就是发生在我身上的事情。 如果要聚合数据,请使用如下代码计算列数:

df.columns.value_counts()

然后删除重复的列。

【讨论】:

以上是关于错误无法处理 groupby 子句中的非唯一多索引是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

在 groupby 熊猫对象上应用 rolling() 时,多索引重复

多索引上的熊猫数据框 groupby

具有多索引列的 Pandas groupby

Groupby 使用字典的多索引列

Pandas 中的多索引排序

Pandas - Groupby 多索引级别,获取可能的组合,然后转换数据