HOWTO · Pandas

Pandas Dataframe のインデックスとして列を設定する

このチュートリアルでは、Pandas DataFrame のメソッド `set_index()` を使用して列をインデックスに設定する方法と、ファイルの読み込み時に `index_col` パラメーターを使用する方法を説明します。

このページの内容

新しい Pandas DataFrame では、行を識別するために既定の整数インデックスが使われます。意味のある行ラベルを使うには、既存の DataFrame に set_index() を呼び出すか、ファイルの読み込み時に read_csv または read_excel に index_col を渡します。前者はデータがすでにメモリ上にある場合に便利で、後者はファイルを読み込む段階でラベルを選択します。以下の例では、結果を比較できるよう同じ小さな人物データを使います。分析で行を簡単に識別できる値を持つ列を選んでください。インデックスに重複値を含めることもできますが、重複したラベルで検索すると複数の行が返る場合があります。

set_index() で DataFrame の列をインデックスにする

set_index() は DataFrame のメソッドです。既定では新しい DataFrame を返し、選択した列を通常の列から取り除きます。元の DataFrame を変更せずに残したい場合は、返された結果を変数に代入します。列名のリストを渡すと、複数の値の組み合わせで各行を識別する MultiIndex を作成できます。選択した値を通常のデータ列としても残すには、drop=False を指定します。

これらの選択はデータへのアクセス方法に影響しますが、行が破棄されるかどうかには影響しません。たとえば、後続のコードで名前をラベルと値の両方として使う場合は名前の列を残し、都市名と年齢の組み合わせが作業に適している場合はそれらを使って MultiIndex を作成します。既存の DataFrame 自体を変更するには、set_index(..., inplace=True) を使います。この場合、DataFrame が変更され、戻り値は None です。通常は、既定で返される DataFrame を代入するほうが動作を追いやすく、元のデータも残せます。通常のインデックスに戻すには、reset_index() を呼び出します。現在のインデックス値が列に移され、既定では新しい整数インデックスが結果に付与されます。これは、データのエクスポート前や、後続の処理でラベルを通常の列として扱う必要がある場合に便利です。

次の例では人物の DataFrame を作成し、1列と2列からそれぞれインデックスを作ります。また、行ラベルに使いながら名前の列を保持する方法も示します。

import pandas as pd

people = pd.DataFrame({
    "Name": ["Alice", "Bob", "Charlie"],
    "City": ["New York", "Los Angeles", "Chicago"],
    "Age": [25, 30, 35],
})

by_name = people.set_index("Name")
by_city_and_age = people.set_index(["City", "Age"])
with_name_column = people.set_index("Name", drop=False)

print(by_name)

ここでは、by_name の行ラベルに名前が使われ、データ列として City と Age が残ります。by_city_and_age は選択した2列を MultiIndex として使い、with_name_column は名前をラベルに使うと同時に Name 列も保持します。各代入で別々の DataFrame が作られるため、people は元の列と既定のインデックスを持つ状態で引き続き利用できます。print 文は1列を使った結果を表示しますが、ほかの2つの変数も同様に確認できます。通常の整数インデックスに戻して、インデックス値を列に戻すには、by_name.reset_index() を呼び出します。これは別の DataFrame を返すため、リセット後のデータで作業を続ける場合は、その結果を代入できます。コード例に表示される列ラベルは英語のままです。

CSV または Excel ファイルの読み込み時に index_col でインデックスを設定する

データの取得元がファイルの場合は、読み込み時にインデックスを選択できます。この自己完結した CSV の例では、上の DataFrame と同じ列名とレコードを使います。StringIO を使うとサンプル文字列をそのまま read_csv に読み込ませられます。CSV ファイルが手元にある場合は、"people.csv" のようなファイルパスに置き換えて呼び出せます。

from io import StringIO
import pandas as pd

csv_data = StringIO("""Name,City,Age
Alice,New York,25
Bob,Los Angeles,30
Charlie,Chicago,35
""")
people = pd.read_csv(csv_data, index_col="Name")

print(people)

index_col="Name" 引数はヘッダー名で列を選択するため、結果のインデックスと残りのデータ列は最初の例の by_name と一致します。数値の index_col を指定すると、代わりに列を0始まりの位置で選択します。最初の列の位置は 0 です。ヘッダー名を使うと選択が明示的になり、列の順序にも左右されにくくなります。複数の列を選択するには、index_col=["City", "Age"] のようなリストを渡して、読み込み時に MultiIndex を作ります。Excel ブックの場合は、対応する読み込み呼び出し pd.read_excel("people.xlsx", index_col="Name") を使います。読み込むにはブックが利用可能であることに加え、pandas に対象形式に対応した Excel エンジンがインストールされている必要があります。ここではブックが提供されていないため、Excel の呼び出しは書き方の例として示しています。ヘッダーの誤記やファイル内の列順の変更がある場合は、意図したフィールドが選ばれるよう、インデックスを指定する前にファイルの列名を確認してください。コード例に表示される列ラベルは英語のままです。