pandas.DataFrameの行名・列名の変更

Modified: | Tags: Python, pandas

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.DataFramerename()メソッドを使うと、任意の行名・列名を変更できる。

基本的な使い方

引数indexおよびcolumnsに、{元の値: 新しい値}のように辞書dictで元の値と新しい値を指定する。

indexが行名でcolumnsが列名。行名・列名のいずれかのみを変更したい場合は、引数indexcolumnsのどちらか一方だけを指定すればよい。

新たな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が返される。引数inplaceTrueにすると、元の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()がある。

引数に指定した文字列が列名の先頭または末尾に追加される。

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.DataFrameset_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を更新したい場合は、引数copyFalseとして上書きすることがリリースノートで推奨されている。

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.DataFrameindex, 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や呼び出し可能オブジェクトを指定する。ここでは例を省略するが、引数inplaceTrueとすると元のオブジェクトが変更される。

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()メソッドも使用可能。

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

関連カテゴリー

関連記事