簡體   English   中英

從具有復合(分層)索引的 Pandas 數據框中選擇行

[英]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']

沒有。 那也失敗了。

那么如何選擇所有行:

  1. 組 1 == 'a'
  2. group1 == 'a' & group2 == 'c'
  3. 組 2 == 'c'
  4. ['a','b','c'] 中的組 1

嘗試使用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']

因為group1group2是索引。 請原諒我之前的嘗試!

要僅獲得第二個索引,我認為您必須交換索引:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM