pandas の MultiIndex を使う場合、インデックスやカラムの指定をスライスで行うとエラーになることがあります。
1 2 |
KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (0)' |
MultiIndex で スライスを使う場合は、インデックスがソートされている必要があるようです。
- 目次 -
スポンサーリンク
例
エラーになる例
インデックスを MultiIndex で階層化し、順番を B → A と逆順にしてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import pandas as pd from pandas import DataFrame df = DataFrame([[1,2],[10,20],[100,200],[1000,2000],[10000,20000]], index=[list('BBBAA'), list('abcab')], columns=['c1','c2']) #-------------------- # c1 c2 # B a 1 2 # b 10 20 # c 100 200 # A a 1000 2000 # b 10000 20000 #-------------------- ↑ # インデックスが B → A と逆順になっている # # スライスで指定(エラー) # df.loc[pd.IndexSlice[:,'b'], :] #---------------------------------------------------------------------- # KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (0)' #---------------------------------------------------------------------- # これが 2 じゃないとダメらしい df.index.lexsort_depth # -> 0 |
対処
対処法として、インデックスでソートします。ソートには sortlevel を使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
df.sortlevel(level=0, inplace=True) #-------------------- # c1 c2 # A a 1000 2000 # b 10000 20000 # B a 1 2 # b 10 20 # c 100 200 #-------------------- ↑ # インデックスを A → B にソート # # スライスで指定(正常) # df.loc[pd.IndexSlice[:,'b'], :] #-------------------- # c1 c2 # A b 10000 20000 # B b 10 20 #-------------------- df.index.lexsort_depth # -> 2 |
列が MultiIndex の場合も
列が MultiIndex 化されている場合も同様で、sortlevel でソートします。オプション axis=1 を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
df2 = DataFrame([[1,10,100,1000,10000],[2,20,200,2000,20000]], index=['1','2'], columns=pd.MultiIndex.from_tuples([('B', 'a'),('B', 'b'),('B', 'c'),('A', 'a'),('A', 'b')])) #---------------------------- # B A # カラムが B → A と逆順になっている # a b c a b # 1 1 10 100 1000 10000 # 2 2 20 200 2000 20000 #---------------------------- df2.sortlevel(level=0, axis=1, inplace=True) #---------------------------- # A B # カラムを A → B にソート # a b a b c # 1 1000 10000 1 10 100 # 2 2000 20000 2 20 200 #---------------------------- df2.loc[:, pd.IndexSlice[:,'b']] #--------------- # A B # b b # 1 10000 10 # 2 20000 20 #--------------- |