33

これは些細なことだと思いますが、階層キーの値に基づいて 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']

いいえ。それも失敗します。

では、次のすべての行を選択するにはどうすればよいですか。

  1. group1 == 'a'
  2. グループ 1 == 'a' & グループ 2 == 'c'
  3. group2 == 'c'
  4. ['a','b','c'] の group1
4

3 に答える 3

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
于 2012-08-13T21:37:08.807 に答える
9

次のような構文が機能します。

df.ix['a']
df.ix['a'].ix['c']

以来group1group2はインデックスです。私の以前の試みを許してください!

2番目のインデックスのみを取得するには、インデックスを交換する必要があると思います。

df.swaplevel(0,1).ix['c']

しかし、私が間違っていれば、Wesが私を訂正すると確信しています。

于 2012-08-13T20:26:38.163 に答える
1

Python 0.19.0 では、ここで説明されている新しいアプローチが提案されています1。彼らが示した最も明確な例は、4 レベルのインデックスからスライスした次の例だと思います。これがデータフレームの作成方法です。

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 を指定しています。

于 2016-10-20T09:02:01.477 に答える