環境
- Python 3.11.2
- pandas 2.0.2
何が起きたか
列がMultiIndex
であるDataFrameがあります。このDataFrameの列名を、pandas.DataFrame.rename関数で変えたいです。
In [303]: data = {("japan","male"):[1,2,3], ("japan","female"):[11,12,13], ("us","male"):[2,3,4]}
In [304]: df = pandas.DataFrame(data)
In [305]: df
Out[305]:
japan us
male female male
0 1 11 2
1 2 12 3
2 3 13 4
columns
にタプルで列を指定しても、列名は変更されませんでした。
# 列名は変更されない
In [310]: df.rename(columns={("us","male"):("US","MALE")})
Out[310]:
japan us
male female male
0 1 11 2
1 2 12 3
2 3 13 4
解決
rename
関数のcolumns
引数にタプルではなく文字列を指定する
タプルで複数要素(ヘッダ1行目と2行目)を指定するのではなく、文字列で1個の要素を指定すれば、変更できました。
In [308]: df.rename(columns={"japan":"JAPAN"})
Out[308]:
JAPAN us
male female male
0 1 11 2
1 2 12 3
2 3 13 4
In [309]: df.rename(columns={"male":"MALE"})
Out[309]:
japan us
MALE female MALE
0 1 11 2
1 2 12 3
2 3 13 4
level
引数を指定すれば、rename対象のヘッダ行を指定することもできます。
In case of a MultiIndex, only rename labels in the specified level.
rename
関数を使わずにcolumns
プロパティに直接指定する
columns
引数に直接MultiIndex
を指定するのが、たぶん一番分かりやすくてハマらないと思います。
In [319]: df2.columns = pandas.MultiIndex.from_tuples([("japan","male"), ("japan","female"), ("US","MALE")])
In [320]: df2
Out[320]:
japan US
male female MALE
0 1 11 2
1 2 12 3
2 3 13 4
試したけどできなかったこと
mapperを指定する
rename
関数には変換用の関数も指定できます。しかし、関数はヘッダの要素ごとに関数が呼ばれるので、期待通り変更できませんでした
In [49]: def mapper(col):
...: print(col)
...: if col == ("us","male"):
...: return ("US","MALE")
...: return col
...:
In [50]: df.rename(mapper, axis="columns")
japan
japan
us
male
female
male
Out[50]:
japan us
male female male
0 1 11 2
1 2 12 3
2 3 13 4