我已经读了一百万遍了,但是我从来没有想过,所以我仍然在想如何使用loc
来用MultiIndex
切分DataFrame
。
我将从this SO answer中的DataFrame
开始:
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
要只选择A0
和C1
值,我可以:
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
它还可以从三个级别中进行选择,甚至可以使用元组:
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
到目前为止,直觉和才华横溢。
为什么我不能从第一个索引级别中选择所有值?
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
行为似乎不一致。
为了安全(从某种意义上说:这在所有情况下都有效),您需要对行索引和列进行索引,您可以使用
pd.IndexSlice
轻松地执行此操作:这里
idx[:, :, 'C1', :]
是一种更容易编写[slice(None), slice(None),'C1', slice(None)]
的方法。您也可以使用较短的np.s_
,而不是pd.IndexSlice
。我不太清楚其他的工作原理。但请参见文档中的注释:http://pandas.pydata.org/pandas-docs/stable/advanced.html#using-slicers(第一个红色警告框),其中说明:
这不起作用的原因是需要指定索引轴(在http://pandas.pydata.org/pandas-docs/stable/advanced.html中提到)。解决问题的另一种方法是这样做:
当索引相似或包含相似值时,Pandas有时会感到困惑。如果要使用名为“C1”的列或其他列,则还需要在此样式的切片/选择下执行此操作。
相关问题 更多 >
编程相关推荐