pandas.DataFrameの列をインデックス(行名)に割り当てるset_index
pandas.DataFrame
のset_index()
メソッドを使うと、既存の列をインデックスindex
(行名、行ラベル)に割り当てることができる。インデックスに一意の名前を指定しておくと、loc
やat
で要素を選択・抽出するとき分かりやすいので便利。
反対にindex
をデータ列にするにはreset_index()
を使う。
index
の一部を変更したり全体をリストなどで置き換えたりする方法については以下の記事を参照。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。例として以下のデータを使用する。
import pandas as pd
print(pd.__version__)
# 2.1.4
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
set_index()の使い方
基本的な使い方
第一引数keys
にインデックスとして使用する列の列名(列ラベル)を指定する。指定した列がindex
に設定される。
print(df.set_index('name'))
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
指定した列をそのまま残す: 引数drop
デフォルトでは、インデックスに指定した列はデータ列から削除される。引数drop=False
とすると、指定列がindex
に設定された上でデータ列にも残る。
print(df.set_index('name', drop=False))
# name age state point
# name
# Alice Alice 24 NY 64
# Bob Bob 42 CA 92
# Charlie Charlie 18 CA 70
# Dave Dave 68 TX 70
# Ellen Ellen 24 CA 88
# Frank Frank 30 NY 57
マルチインデックスを割り当て: 複数列指定、引数append
set_index()
で複数の列を階層的にインデックスとするマルチインデックスを割り当てることもできる。マルチインデックスについては以下の記事を参照。
複数の列をリストで指定
第一引数keys
に列名(列ラベル)のリストを指定すると、複数の列がマルチインデックスとして割り当てられる。
print(df.set_index(['state', 'name']))
# age point
# state name
# NY Alice 24 64
# CA Bob 42 92
# Charlie 18 70
# TX Dave 68 70
# CA Ellen 24 88
# NY Frank 30 57
sort_index()
でソートすると綺麗に表示される。
print(df.set_index(['state', 'name']).sort_index())
# age point
# state name
# CA Bob 42 92
# Charlie 18 70
# Ellen 24 88
# NY Alice 24 64
# Frank 30 57
# TX Dave 68 70
指定列をインデックスの階層に追加: 引数append
デフォルトではset_index()
に列を指定すると、元のインデックスは削除される。
df_name = df.set_index('name')
print(df_name)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
print(df_name.set_index('state'))
# age point
# state
# NY 24 64
# CA 42 92
# CA 18 70
# TX 68 70
# CA 24 88
# NY 30 57
引数append
をTrue
とすると、元のインデックスに加えて、指定した列が新たな階層のインデックスとして追加される。
df_mi = df_name.set_index('state', append=True)
print(df_mi)
# age point
# name state
# Alice NY 24 64
# Bob CA 42 92
# Charlie CA 18 70
# Dave TX 68 70
# Ellen CA 24 88
# Frank NY 30 57
追加された列は一番下の階層となる。階層を入れ替えるにはswaplevel()
を使う。
print(df_mi.swaplevel(0, 1))
# age point
# state name
# NY Alice 24 64
# CA Bob 42 92
# Charlie 18 70
# TX Dave 68 70
# CA Ellen 24 88
# NY Frank 30 57
元のインデックスを列として残す
set_index()
で新しいインデックスを指定すると元のインデックスは削除される。
元のインデックスを残すには、インデックスを0始まりの連番に振り直すreset_index()
を使う。
df_name = df.set_index('name')
print(df_name)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
print(df_name.reset_index())
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
インデックスを別の列に変更(再設定)するにはreset_index()
のあとでset_index()
を用いればよい。一気に書くと以下のようになる。
print(df_name.reset_index().set_index('state'))
# name age point
# state
# NY Alice 24 64
# CA Bob 42 92
# CA Charlie 18 70
# TX Dave 68 70
# CA Ellen 24 88
# NY Frank 30 57
新しいインデックスに重複がないかチェック: 引数verify_integrity
デフォルトでは、新しいインデックスに重複があってもそのまま使用される。引数verify_integrity
をTrue
とすると、重複があるとエラーになる。
print(df.set_index('state'))
# name age point
# state
# NY Alice 24 64
# CA Bob 42 92
# CA Charlie 18 70
# TX Dave 68 70
# CA Ellen 24 88
# NY Frank 30 57
# print(df.set_index('state', verify_integrity=True))
# ValueError: Index has duplicate keys: Index(['CA', 'NY'], dtype='object', name='state')
元のオブジェクトを変更: 引数inplace
デフォルトではset_index()
で元のオブジェクトは変更されず、新たなオブジェクトが返される。引数inplace
をTrue
とすると、元のオブジェクトが変更される。
df.set_index('name', inplace=True)
print(df)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
CSVファイルなどの読み込み時にインデックスを指定
pd.read_csv()
でCSVファイルをDataFrame
として読み込むときにインデックスとする列を指定できる。引数index_col
に列番号を指定するとその列がインデックスとなる。
df_name = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0)
print(df_name)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
インデックス(行名)を使って行や要素を選択・抽出
インデックス(行名、行ラベル)に一意の文字列などを指定すると、行や要素を名前で選択・抽出できる。
df_name = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0)
print(df_name)
# age state point
# name
# Alice 24 NY 64
# Bob 42 CA 92
# Charlie 18 CA 70
# Dave 68 TX 70
# Ellen 24 CA 88
# Frank 30 NY 57
print(df_name.loc['Bob'])
# age 42
# state CA
# point 92
# Name: Bob, dtype: object
print(df_name.at['Bob', 'age'])
# 42
at
やloc
による要素や行・列の選択、インデックス指定による行・列の選択についての詳細は以下の記事を参照。