マルチインデックスデータフレームを使用した `.loc` と `.iloc` 質問する

マルチインデックスデータフレームを使用した `.loc` と `.iloc` 質問する

MultiIndex 化された DataFrame にインデックスを付ける場合、外側のレベルを参照し.ilocながらインデックスの「内側のレベル」を参照していると想定されるようです。.loc

例えば:

np.random.seed(123)
iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]
idx = pd.MultiIndex.from_product(iterables, names=['first', 'second'])
df = pd.DataFrame(np.random.randn(8, 4), index=idx)

# .loc looks at the outer index:

print(df.loc['qux'])
# df.loc['two'] would throw KeyError
              0        1        2        3
second                                    
one    -1.25388 -0.63775  0.90711 -1.42868
two    -0.14007 -0.86175 -0.25562 -2.79859

# while .iloc looks at the inner index:

print(df.iloc[-1])
0   -0.14007
1   -0.86175
2   -0.25562
3   -2.79859
Name: (qux, two), dtype: float64

2つの質問:

まず、これはなぜでしょうか? これは意図的な設計上の決定でしょうか?

次に、.ilocインデックスの外側のレベルを参照して、以下の結果を生成するために、 を使用できますか? 最初に でインデックスの最後のメンバーを見つけてget_level_values、次にそれを使用して -index を実行できることはわかっていますが、ファンキーな構文またはこのケース専用に設計された既存の関数.locを使用して、より直接的に実行できるかどうか疑問に思っています。.iloc

# df.iloc[-1]
qux   one     0.89071  1.75489  1.49564  1.06939
      two    -0.77271  0.79486  0.31427 -1.32627

ベストアンサー1

はい、これは意図的な設計決定:

.iloc厳密な位置インデックスであり、ではない構造をまったく考慮せず、最初の実際の動作だけを考慮します。 ....loc するレベルの動作を考慮に入れる。[強調追加]

したがって、質問で与えられた望ましい結果は、 では柔軟に実現できません.iloc。いくつかの同様の質問で使用されている最も近い回避策は、

print(df.loc[[df.index.get_level_values(0)[-1]]])
                    0        1        2        3
first second                                    
qux   one    -1.25388 -0.63775  0.90711 -1.42868
      two    -0.14007 -0.86175 -0.25562 -2.79859

使用二重括弧最初のインデックス レベルが保持されます。

おすすめ記事