我怀疑这是微不足道的,但我还没有发现让我根据分层键的值从Pandas数据帧中选择行的咒语。因此,例如,假设我们有以下数据框:
import pandas
df = pandas.DataFrame({'group1': ['a','a','a','b','b','b'],
'group2': ['c','c','d','d','d','e'],
'value1': [1.1,2,3,4,5,6],
'value2': [7.1,8,9,10,11,12]
})
df = df.set_index(['group1', 'group2'])
df看起来像我们期望的那样:
如果df未在group1上编入索引,我可以执行以下操作:
df['group1' == 'a']
但是这个带有索引的数据帧失败了。所以也许我应该把它想象成一个带有分层索引的Pandas系列:
df['a','c']
不。那也失败了。
那么如何选择所有行:
答案 0 :(得分:49)
尝试使用xs
非常精确:
In [5]: df.xs('a', level=0)
Out[5]:
value1 value2
group2
c 1.1 7.1
c 2.0 8.0
d 3.0 9.0
In [6]: df.xs('c', level='group2')
Out[6]:
value1 value2
group1
a 1.1 7.1
a 2.0 8.0
答案 1 :(得分:9)
以下语法将起作用:
df.ix['a']
df.ix['a'].ix['c']
因为group1
和group2
是索引。请原谅我以前的尝试!
要获得第二个索引,我认为你必须交换索引:
df.swaplevel(0,1).ix['c']
但我确信如果我错了,Wes会纠正我。
答案 2 :(得分:1)
在Python 0.19.0中有一种新的建议方法,在此处解释1。我相信他们给出的最明显的例子如下,他们从四级索引切片。这就是数据帧的制作方式:
In [46]: def mklbl(prefix,n):
....: return ["%s%s" % (prefix,i) for i in range(n)]
....:
In [47]: miindex = pd.MultiIndex.from_product([mklbl('A',4),
....: mklbl('B',2),
....: mklbl('C',4),
....: mklbl('D',2)])
....:
In [48]: micolumns = pd.MultiIndex.from_tuples([('a','foo'),('a','bar'),
....: ('b','foo'),('b','bah')],
....: names=['lvl0', 'lvl1'])
....:
In [49]: dfmi = pd.DataFrame(np.arange(len(miindex)*len(micolumns)).reshape((len(miindex),len(micolumns))),
....: index=miindex,
....: columns=micolumns).sort_index().sort_index(axis=1)
....:
In [50]: dfmi
Out[50]:
lvl0 a b
lvl1 bar foo bah foo
A0 B0 C0 D0 1 0 3 2
D1 5 4 7 6
C1 D0 9 8 11 10
D1 13 12 15 14
C2 D0 17 16 19 18
D1 21 20 23 22
C3 D0 25 24 27 26
... ... ... ... ...
A3 B1 C0 D1 229 228 231 230
C1 D0 233 232 235 234
D1 237 236 239 238
C2 D0 241 240 243 242
D1 245 244 247 246
C3 D0 249 248 251 250
D1 253 252 255 254
这就是他们选择不同行的方式:
In [51]: dfmi.loc[(slice('A1','A3'),slice(None), ['C1','C3']),:]
Out[51]:
lvl0 a b
lvl1 bar foo bah foo
A1 B0 C1 D0 73 72 75 74
D1 77 76 79 78
C3 D0 89 88 91 90
D1 93 92 95 94
B1 C1 D0 105 104 107 106
D1 109 108 111 110
C3 D0 121 120 123 122
... ... ... ... ...
A3 B0 C1 D1 205 204 207 206
C3 D0 217 216 219 218
D1 221 220 223 222
B1 C1 D0 233 232 235 234
D1 237 236 239 238
C3 D0 249 248 251 250
D1 253 252 255 254
非常简单,在df.loc[(indices),:]
中,您可以指定要从每个级别选择的索引,从最高级别到最低级别。如果您不想选择最低级别的索引,则可以省略指定它们。如果您不想在其他指定级别之间进行切片,则添加slice(None)
。这两种情况都显示在示例中,其中省略了级别D,并且在A和C之间指定了级别B.