pandas.DataFrameの行名・列名の変更
pandas.DataFrameの行名(index, インデックス)・列名(columns)を変更するには、rename()メソッドやset_axis()メソッドなどを使う。
既存の列をインデックスに設定するset_index()というメソッドもある。
本記事のサンプルコードのpandasのバージョンは以下の通り。バージョンによって仕様が異なる可能性があるので注意。以下のpandas.DataFrameを例として使う。
import pandas as pd
print(pd.__version__)
# 2.0.3
df = pd.DataFrame({'A': [11, 21, 31], 'B': [12, 22, 32], 'C': [13, 23, 33]},
index=['ONE', 'TWO', 'THREE'])
print(df)
# A B C
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
任意の行名・列名を変更: rename()
pandas.DataFrameのrename()メソッドを使うと、任意の行名・列名を変更できる。
基本的な使い方
引数indexおよびcolumnsに、{元の値: 新しい値}のように辞書dictで元の値と新しい値を指定する。
indexが行名でcolumnsが列名。行名・列名のいずれかのみを変更したい場合は、引数indexとcolumnsのどちらか一方だけを指定すればよい。
新たなpandas.DataFrameが返され、元のpandas.DataFrameは変更されない。
df_new = df.rename(columns={'A': 'Col_1'}, index={'ONE': 'Row_1'})
print(df_new)
# Col_1 B C
# Row_1 11 12 13
# TWO 21 22 23
# THREE 31 32 33
print(df)
# A B C
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
第一引数mapperに辞書、引数axisに行名・列名のどちらを対象にするか指定する方法もある。0または'index'だと行名、1またはcolumnsだと列名が対象になる。この場合、行名と列名を同時に変更することはできない。
print(df.rename({'A': 'Col_1'}, axis='columns'))
# Col_1 B C
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
複数の行名・列名を変更
複数の行名・列名の値を一括で変更することもできる。辞書の要素を追加すればよい。
print(df.rename(columns={'A': 'Col_1', 'C': 'Col_3'}))
# Col_1 B Col_3
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
元のオブジェクトを変更: 引数inplace
デフォルトでは元のpandas.DataFrameは変更されず、新しいpandas.DataFrameが返される。引数inplaceをTrueにすると、元のpandas.DataFrameが変更される。
df_copy = df.copy()
df_copy.rename(columns={'A': 'Col_1'}, index={'ONE': 'Row_1'}, inplace=True)
print(df_copy)
# Col_1 B C
# Row_1 11 12 13
# TWO 21 22 23
# THREE 31 32 33
ラムダ式や関数で一括処理
rename()メソッドの引数indexおよびcolumnsには呼び出し可能オブジェクト(関数など)を指定することもできる。
大文字・小文字を変換する関数を適用する例。
print(df.rename(columns=str.lower, index=str.title))
# a b c
# One 11 12 13
# Two 21 22 23
# Three 31 32 33
ラムダ式(無名関数)で処理することも可能。繰り返したり、末尾に追加したりする例。
print(df.rename(columns=lambda s: s * 3, index=lambda s: s + '!!'))
# AAA BBB CCC
# ONE!! 11 12 13
# TWO!! 21 22 23
# THREE!! 31 32 33
列名の先頭・末尾に文字列を追加するには専用のメソッドが用意されている。次に説明する。
列名にプレフィックス、サフィックスを追加: add_prefix(), add_suffix()
列名にプレフィックス(接頭辞)、サフィックス(接尾辞)を追加するためのメソッド、add_prefix()とadd_suffix()がある。
- pandas.DataFrame.add_prefix — pandas 2.0.3 documentation
- pandas.DataFrame.add_suffix — pandas 2.0.3 documentation
引数に指定した文字列が列名の先頭または末尾に追加される。
print(df.add_prefix('X_'))
# X_A X_B X_C
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
print(df.add_suffix('_X'))
# A_X B_X C_X
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
バージョン2.0.0で引数axisが追加された。0または'index'だと行名、1またはcolumnsだと列名が対象になる。省略した場合は上の例のように列名が対象となる。
print(df.add_prefix('X_', axis=0))
# A B C
# X_ONE 11 12 13
# X_TWO 21 22 23
# X_THREE 31 32 33
print(df.add_suffix('_X', axis='index'))
# A B C
# ONE_X 11 12 13
# TWO_X 21 22 23
# THREE_X 31 32 33
2.0.0より前のバージョンでは列名しか処理できない。行名にプレフィックスやサフィックスを追加したい場合は、上述のようにrename()メソッドで引数indexにラムダ式を指定する。
なお、add_prefix(), add_suffix()には引数inplaceは実装されていない。元のオブジェクトを更新したい場合はdf = df.add_prefix()のように上書きすればよい。
行名・列名をすべて変更
行名・列名をすべて変更するには、set_axis()メソッドを使うか、index, columns属性を更新する。
set_axis()
pandas.DataFrameのset_axis()メソッドを使うと、すべての行名・列名を変更できる。
第一引数labelsに新しい行名または列名をリストやタプルなどのlist-likeオブジェクトで指定する。
引数axisで行名・列名どちらを対象とするかを指定する。0または'index'で行名、1またはcolumnsで列名が対象となる。省略した場合は行名が対象となる。
print(df.set_axis(['Row_1', 'Row_2', 'Row_3'], axis=0))
# A B C
# Row_1 11 12 13
# Row_2 21 22 23
# Row_3 31 32 33
print(df.set_axis(['Row_1', 'Row_2', 'Row_3'], axis='index'))
# A B C
# Row_1 11 12 13
# Row_2 21 22 23
# Row_3 31 32 33
print(df.set_axis(['Col_1', 'Col_2', 'Col_3'], axis=1))
# Col_1 Col_2 Col_3
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
print(df.set_axis(['Col_1', 'Col_2', 'Col_3'], axis='columns'))
# Col_1 Col_2 Col_3
# ONE 11 12 13
# TWO 21 22 23
# THREE 31 32 33
print(df.set_axis(['Row_1', 'Row_2', 'Row_3']))
# A B C
# Row_1 11 12 13
# Row_2 21 22 23
# Row_3 31 32 33
第一引数に指定したリストなどのサイズ(要素数)が行数・列数と一致していないとエラーになるので注意。
# print(df.set_axis(['Row_1', 'Row_2', 'Row_3', 'Row_4']))
# ValueError: Length mismatch: Expected axis has 3 elements, new values have 4 elements
デフォルトでは元のpandas.DataFrameは変更されず、新しいpandas.DataFrameが返される。以前は引数inplaceがあったが、バージョン1.5.0で廃止された。元のpandas.DataFrameを更新したい場合は、引数copyをFalseとして上書きすることがリリースノートで推奨されている。
df_copy = df.copy()
df_copy = df_copy.set_axis(['Row_1', 'Row_2', 'Row_3'], copy=False)
print(df_copy)
# A B C
# Row_1 11 12 13
# Row_2 21 22 23
# Row_3 31 32 33
index, columns属性を更新
pandas.DataFrameのindex, columns属性を更新することもできる。
index, columns属性には、リストやタプルなどのlist-likeオブジェクトを指定できる。当然ながら元のpandas.DataFrameがそのまま更新される。
df.index = ['Row_1', 'Row_2', 'Row_3']
df.columns = ['Col_1', 'Col_2', 'Col_3']
print(df)
# Col_1 Col_2 Col_3
# Row_1 11 12 13
# Row_2 21 22 23
# Row_3 31 32 33
リストなどのサイズ(要素数)が行数・列数と一致していないとエラーになるので注意。
# df.index = ['Row_1', 'Row_2', 'Row_3', 'Row_4']
# ValueError: Length mismatch: Expected axis has 3 elements, new values have 4 elements
pandas.Seriesの場合
これまでのpandas.DataFrameの例と同様に、pandas.Seriesのラベル名(index)も変更できる。
以下のpandas.Seriesを例とする。
s = pd.Series([1, 2, 3], index=['ONE', 'TWO', 'THREE'])
print(s)
# ONE 1
# TWO 2
# THREE 3
# dtype: int64
rename()メソッド。第一引数indexに辞書dictや呼び出し可能オブジェクトを指定する。ここでは例を省略するが、引数inplaceをTrueとすると元のオブジェクトが変更される。
print(s.rename({'ONE': 'a', 'THREE': 'c'}))
# a 1
# TWO 2
# c 3
# dtype: int64
print(s.rename(str.lower))
# one 1
# two 2
# three 3
# dtype: int64
add_prefix(), add_suffix()メソッドも使用可能。
- pandas.Series.add_prefix — pandas 2.0.3 documentation
- pandas.Series.add_suffix — pandas 2.0.3 documentation
print(s.add_prefix('X_'))
# X_ONE 1
# X_TWO 2
# X_THREE 3
# dtype: int64
print(s.add_suffix('_X'))
# ONE_X 1
# TWO_X 2
# THREE_X 3
# dtype: int64
set_axis()メソッドも提供されている。
print(s.set_axis(['a', 'b', 'c']))
# a 1
# b 2
# c 3
# dtype: int64
index属性を更新することもできる。
s.index = ['A', 'B', 'C']
print(s)
# A 1
# B 2
# C 3
# dtype: int64