Index Levels
outside = ['G1','G1','G1','G2','G2','G2']
inside = [1,2,3,1,2,3]
hier_index = list(zip(outside,inside))
hier_index = pd.MultiIndex.from_tuples(hier_index)
df = pd.DataFrame(np.random.randn(6,2),index=hier_index,columns=['A','B'])
上記のように設定したマルチラベルにおいて値を抽出するとき
上は動くのに下は動かない理由が分からない。
df.loc['G1'].loc[1]['B']
df.loc['G1'][1]['B']
#チャッピー回答メモ
結論
df.loc['G1'].loc[1]['B'] が動作する一方で df.loc['G1'][1]['B'] が動かないのは、pandas におけるデータ型の違いとアクセス方法の解釈によるものです。
df.loc['G1'].loc[1]['B'] の動作
df.loc['G1']:
'G1' に対応する行を取得します。
この結果は以下のようなサブデータフレーム(DataFrame)になります:
A B
1 0.153661 0.167638
2 -0.765930 0.962299
3 0.902826 -0.537909
.loc[1]:
サブデータフレームから行ラベル 1 を持つ行を取得します。
この結果は1行だけの Series になります:
A 0.153661
B 0.167638
Name: 1, dtype: float64
['B']:
Series からインデックス 'B' に対応する値を取得します。
この一連の操作が正常に動作し、'B' に対応する値が返されます。
df.loc['G1'][1]['B'] のエラー
df.loc['G1']:
'G1' に対応するサブデータフレームを取得します(上記と同様)。
[1]:
ここでの [1] は、サブデータフレームに対する操作として解釈されます。
**サブデータフレームに対する角括弧 [] のデフォルトの挙動は「列ラベル」として解釈される」**ため、ここでは列ラベル 1 を探します。
しかし、サブデータフレームの列ラベルは ['A', 'B'] であり、1 という列ラベルは存在しないため、KeyError が発生します。
解決方法
以下のように記述することでエラーを回避できます:
.loc を使用: 行ラベルを明示的に指定するには .loc を使用します。
df.loc['G1'].loc[1]['B'] # 正しく動作
.iloc を使用: インデックス番号(ゼロ始まり)でアクセスする場合は .iloc を使用します。
df.loc['G1'].iloc[0]['B'] # サブデータフレームの最初の行の列 'B' を取得
注意点
角括弧 [] の挙動に注意:
サブデータフレーム(DataFrame)に対する [] はデフォルトで「列ラベル」として解釈されます。
一方、Series に対する [] は「インデックスキー」として解釈されます。
一貫して .loc または .iloc を使う:
.loc は行ラベルや列ラベルに基づいたアクセスをサポートします。
.iloc は行番号や列番号による位置ベースのアクセスをサポートします。