首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DataFrame.loc的“太多索引器”

使用DataFrame.loc的“太多索引器”
EN

Stack Overflow用户
提问于 2015-06-11 12:38:50
回答 2查看 127.6K关注 0票数 47

我已经读过关于切割机的医生上百万次了,但是我从来没有读过它,所以我仍然在努力弄清楚如何使用loc来分割一个DataFrame和一个MultiIndex

我将从DataFrame这就是答案开始

代码语言:javascript
复制
                           value
first second third fourth       
A0    B0     C1    D0          2
                   D1          3
             C2    D0          6
                   D1          7
      B1     C1    D0         10
                   D1         11
             C2    D0         14
                   D1         15
A1    B0     C1    D0         18
                   D1         19
             C2    D0         22
                   D1         23
      B1     C1    D0         26
                   D1         27
             C2    D0         30
                   D1         31
A2    B0     C1    D0         34
                   D1         35
             C2    D0         38
                   D1         39
      B1     C1    D0         42
                   D1         43
             C2    D0         46
                   D1         47
A3    B0     C1    D0         50
                   D1         51
             C2    D0         54
                   D1         55
      B1     C1    D0         58
                   D1         59
             C2    D0         62
                   D1         63

要选择A0C1值,我可以这样做:

代码语言:javascript
复制
In [26]: df.loc['A0', :, 'C1', :]
Out[26]: 
                           value
first second third fourth       
A0    B0     C1    D0          2
                   D1          3
      B1     C1    D0         10
                   D1         11

它还可以从三个级别进行选择,甚至可以使用元组:

代码语言:javascript
复制
In [28]: df.loc['A0', :, ('C1', 'C2'), 'D1']
Out[28]: 
                           value
first second third fourth       
A0    B0     C1    D1          3
             C2    D1          5
      B1     C1    D1         11
             C2    D1         13

到目前为止,直觉和聪明。

那么为什么我不能从第一个索引级别中选择所有的值呢?

代码语言:javascript
复制
In [30]: df.loc[:, :, 'C1', :]
---------------------------------------------------------------------------
IndexingError                             Traceback (most recent call last)
<ipython-input-30-57b56108d941> in <module>()
----> 1 df.loc[:, :, 'C1', :]

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in __getitem__(self, key)
   1176     def __getitem__(self, key):
   1177         if type(key) is tuple:
-> 1178             return self._getitem_tuple(key)
   1179         else:
   1180             return self._getitem_axis(key, axis=0)

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in _getitem_tuple(self, tup)
    694 
    695         # no multi-index, so validate all of the indexers
--> 696         self._has_valid_tuple(tup)
    697 
    698         # ugly hack for GH #836

/usr/local/lib/python2.7/dist-packages/pandas/core/indexing.pyc in _has_valid_tuple(self, key)
    125         for i, k in enumerate(key):
    126             if i >= self.obj.ndim:
--> 127                 raise IndexingError('Too many indexers')
    128             if not self._has_valid_type(k, i):
    129                 raise ValueError("Location based indexing can only have [%s] "

IndexingError: Too many indexers

这肯定不是有意的行为?

注意:我知道这在df.xs('C1', level='third')中是可能的,但是当前的.loc行为似乎不一致。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-01 20:20:06

这不起作用的原因是需要指定索引的轴(在http://pandas.pydata.org/pandas-docs/stable/advanced.html中提到)。解决您的问题的另一种解决方案就是简单地这样做:

代码语言:javascript
复制
df.loc(axis=0)[:, :, 'C1', :]

有时,当指数相似或包含相似值时,熊猫会感到困惑。如果您要有一个名为“C1”的列,那么您也需要在这种切片/选择风格下这样做。

票数 31
EN

Stack Overflow用户

发布于 2015-06-11 13:06:10

为了安全起见(从某种意义上说,这在所有情况下都是有效的),您需要同时索引行索引和列,为此您可以使用pd.IndexSlice轻松地做到这一点:

代码语言:javascript
复制
In [26]: idx = pd.IndexSlice

In [27]: df.loc[idx[:, :, 'C1', :],:]
Out[27]:
                           value
first second third fourth
A0    B0     C1    D0          2
                   D1          3
      B1     C1    D0         10
                   D1         11
A1    B0     C1    D0         18
                   D1         19
      B1     C1    D0         26
                   D1         27
A2    B0     C1    D0         34
                   D1         35
      B1     C1    D0         42
                   D1         43
A3    B0     C1    D0         50
                   D1         51
      B1     C1    D0         58
                   D1         59

在这里,idx[:, :, 'C1', :]是一种更容易编写[slice(None), slice(None),'C1', slice(None)]的方法。您也可以使用更短一些的pd.IndexSlice,而不是np.s_

其他人工作的原因,我不完全确定。但请参阅文档中的注释:http://pandas.pydata.org/pandas-docs/stable/advanced.html#using-slicers (第一个红色警告框),其中声明:

您应该在.loc说明符中指定所有轴,这意味着索引和列的索引器。它们是一些模棱两可的情况,传递的索引器可能被错误地解释为两个轴的索引,而不是行的MuliIndex。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30781037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档