data
というデータフレームがあります。唯一の1つの列ヘッダーの名前を変更する方法例えばgdp
からlog(gdp)
まで?
data =
y gdp cap
0 1 2 5
1 2 3 9
2 8 7 2
3 3 4 7
4 6 7 7
5 4 8 3
6 8 2 8
7 9 9 10
8 6 6 4
9 10 10 7
単一の列の名前を変更する必要がある場合は、はるかに速い実装でlist-comprehension
を使用します。
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
複数の列の名前を変更する必要が生じた場合は、次のような条件式を使用してください。
df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]
または、dictionary
を使用してマッピングを作成し、デフォルト値を古い名前に設定してget
操作でlist-comprehension
を実行します。
col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'} ## key→old name, value→new name
df.columns = [col_dict.get(x, x) for x in df.columns]
タイミング:
%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop
%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop
パンダ内の特定の列の名前を変更する方法
V0.24以降から、一度に1つ(または複数)の列の名前を変更するには、
DataFrame.rename()
withaxis=1
またはaxis='columns'
( axis
引数がv0.21
に導入されました。
Index.str.replace()
文字列/正規表現に基づく置換。
一度にすべてのカラムの名前を変更する必要がある場合は、
DataFrame.set_axis()
axis=1
メソッド。リストのようなシーケンスを渡します。インプレース変更のためのオプションもあります。rename
とaxis=1
df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df
y gdp cap
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
0.21以降では、axis
とともにrename
パラメータを指定できるようになりました。
df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
y log(gdp) cap
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
(rename
はデフォルトではインプレースではないので、結果を元に戻す必要があります。)
この追加は、他のAPIとの一貫性を向上させるために行われました。新しいaxis
引数はcolumns
パラメータに似ています - それらは同じことをします。
df.rename(columns={'gdp': 'log(gdp)'})
y log(gdp) cap
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
rename
は、各列に対して1回呼び出されるコールバックも受け入れます。
df.rename(lambda x: x[0], axis=1)
# df.rename(lambda x: x[0], axis='columns')
y g c
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
この特定のシナリオでは、使用したいと思うでしょう
df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)
Index.str.replace
Pythonの文字列のreplace
メソッドと同様に、pandas IndexとSeries(object dtypeのみ)は文字列と正規表現に基づく置換のための( "ベクトル化された")str.replace
メソッドを定義します。
df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
y log(gdp) cap
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
他の方法に対するこの利点は、str.replace
が正規表現をサポートすることです(デフォルトで有効になっています)。詳しくはドキュメントを参照してください。
set_axis
を使ってaxis=1
にリストを渡すヘッダのリストを付けてset_axis
を呼び出します。リストの長さは列/インデックスサイズと同じでなければなりません。 set_axis
はデフォルトで元のDataFrameを変更しますが、inplace=False
を指定して変更されたコピーを返すことができます。
df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)
cap log(gdp) y
0 x x x
1 x x x
2 x x x
3 x x x
4 x x x
注:将来のリリースでは、inplace
はデフォルトでTrue
になります。
メソッドチェーン
すでにset_axis
を使って列を割り当てる効率的な方法があるのに、なぜdf.columns = ...
を選ぶのですか? [この回答]でTed Petrouによって示されているように、( https://stackoverflow.com/a/46912050/4909087 )set_axis
は、メソッドを連鎖させるときに役立ちます。
比較する
# new for pandas 0.21+
df.some_method1()
.some_method2()
.set_axis()
.some_method3()
Versus
# old way
df1 = df.some_method1()
.some_method2()
df1.columns = columns
df1.some_method3()
前者はより自然で自由に流れる構文です。