pandas の set_index と reset_index でインデックスを操作する

pandas のデータフレームには、行を識別するためのインデックスがあります。set_indexreset_index を使うと、インデックスと列の間で変換ができます。

set_index で列をインデックスにする

特定の列をインデックスに設定するには set_index を使います。

import pandas as pd

df = pd.DataFrame({
    'id': [101, 102, 103],
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [80, 90, 85]
})

df = df.set_index('id')
print(df)

これで id 列がインデックスになり、df.loc[101] のようにアクセスできるようになります。元の id 列は削除されます。

reset_index でインデックスを列に戻す

逆に、インデックスを通常の列に戻すには reset_index を使います。

df = df.reset_index()
print(df)

これでインデックスが 0, 1, 2 という連番に戻り、元のインデックスは id という列になります。

インデックスを削除する

reset_indexdrop=True を指定すると、インデックスを列に追加せずに削除できます。

df = df.reset_index(drop=True)

重複したインデックスを振り直したいときなどに使います。

複数の列をインデックスにする(MultiIndex)

set_index に複数の列を指定すると、階層的なインデックス(MultiIndex)を作成できます。

df = pd.DataFrame({
    'year': [2023, 2023, 2024, 2024],
    'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
    'sales': [100, 150, 120, 180]
})

df = df.set_index(['year', 'quarter'])
print(df)

MultiIndex を使うと、df.loc[2023] で 2023 年のデータ、df.loc[(2023, 'Q1')] で特定の年と四半期のデータにアクセスできます。

MultiIndex を展開する

MultiIndex から元の列に戻すには reset_index を使います。

df = df.reset_index()

特定のレベルだけ戻すこともできます。

# year だけを列に戻す
df = df.reset_index(level='year')

インデックスを残したまま列を追加する

set_index はデフォルトで元の列を削除しますが、drop=False を指定すると列を残せます。

df = pd.DataFrame({
    'id': [1, 2, 3],
    'value': [10, 20, 30]
})

df = df.set_index('id', drop=False)
print(df)
# id がインデックスにもなり、列にも残る

append でインデックスを追加する

既存のインデックスを残したまま、新しいインデックスを追加することもできます。

df = pd.DataFrame({
    'id': [1, 2],
    'category': ['A', 'B'],
    'value': [10, 20]
})

df = df.set_index('id')
df = df.set_index('category', append=True)
print(df)

実用的な場面

merge 前の準備

結合キーをインデックスにしておくと、merge で on の代わりに left_index=True が使えます。

groupby の結果処理

groupby の結果はグループ列がインデックスになるため、reset_index で列に戻すことがよくあります。

インデックスの操作は pandas の基本スキルです。データの読み込み後に適切なインデックスを設定しておくと、その後の操作がしやすくなります。