[英]Selecting rows from a Pandas dataframe with a compound (hierarchical) index
我懷疑這是微不足道的,但我還沒有發現可以讓我根據分層鍵的值從 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']
但是在這個帶有索引的數據幀上失敗了。 所以也許我應該把它想象成一個帶有層次索引的熊貓系列:
df['a','c']
沒有。 那也失敗了。
那么如何選擇所有行:
嘗試使用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
如下語法將起作用:
df.ix['a']
df.ix['a'].ix['c']
因為group1
和group2
是索引。 請原諒我之前的嘗試!
要僅獲得第二個索引,我認為您必須交換索引:
df.swaplevel(0,1).ix['c']
但我敢肯定,如果我錯了,韋斯會糾正我的。
在 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 級。
或者,您可以使用query
:
1. group1 == 'a'
In [11]: df.query('group1 == "a"')
Out[11]:
value1 value2
group1 group2
a c 1.1 7.1
c 2.0 8.0
d 3.0 9.0
2. group1 == 'a' & group2 == 'c'
In [12]: df.query('group1 == "a" & group2 == "c"')
Out[12]:
value1 value2
group1 group2
a c 1.1 7.1
c 2.0 8.0
3. group2 == 'c'
In [13]: df.query('group2 == "c"')
Out[13]:
value1 value2
group1 group2
a c 1.1 7.1
c 2.0 8.0
4. group1 in ['a','b','c']
In [14]: df.query('group1 in ["a", "b", "c"]')
Out[14]:
value1 value2
group1 group2
a c 1.1 7.1
c 2.0 8.0
d 3.0 9.0
b d 4.0 10.0
d 5.0 11.0
e 6.0 12.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.