パンダの特定の列の名前を変更する


182

というデータフレームを持っていdataます。唯一の列ヘッダーの名前を変更するにはどうすればよいですか?たとえばgdplog(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

7
間違いなく重複はありますが、「パンダの列の名前を変更する」では、名前を変更するために単一の列要素を選択できるかどうかはすぐにはわかりませんでした。もちろん、振り返ってみるとそれは明らかであり、私が深く掘っていた場合、おそらくそれを理解したでしょうが、この質問/回答はそれを指摘するのに優れていると思います。
jeremiahbuddha 2013年

回答:


359
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

renameそれはのためのparamとしてのdictを受け入れることを示しcolumnsあなただけの単一のエントリで辞書を渡すようにします。

関連も参照


3
これは大きなデータフレームで非常に長い時間がかかるので、メモリ内のデータフレーム全体を何らかの方法でコピーすると思いますか?
elgehelge 2015年

1
それはすべきではない@elgehelge、ほとんどのパンダ操作はコピーを返し、一部は受け入れるinplaceことは、このparamは、これはバグでは無視していた場合、PARAMを、あなたとし、PARAMせずにタイミングを行うことができ、また、のような何かをしようとnew_df = df.rename(columns={'new_name':'old_name'})し、このかどうかを確認しますより速いかどうか
EdChum 2015年

1
@ EdChumありがとう。inplaceパラメータを削除すると、時間が2倍の14秒から26秒にほぼ倍増しました。しかし、14秒はまだかなり長い時間がちょうどヘッダーを変更するには...
elgehelge

2
1つだけ注意してください。ターゲット列が存在しない場合(名前のスペルを間違えるなど)、エラーや警告は発生せず、何も行われません。
Amir

1
@Quastiatリストを理解することで、これらの単純な演算の一部がより高速になる理由が少し落ち込んでいます。基本的には、非常に大きなdfがない限り、大きなdfで多くの列の名前を変更しない限り、実際には問題になりません
EdChum

27

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]

または、aを使用してマッピングを作成し、デフォルト値を古い名前に設定しdictionarylist-comprehensionwith with get操作を実行します。

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

私はこの方法を使用するのが大好きだが、残念ながらそれは動作しませんpd.merge_asof()、それは表現:(だから。
thdoan

14

パンダの特定の列の名前を変更するにはどうすればよいですか?

v0.24以降、一度に1つ以上の列の名前を変更するには、

すべての列の名前を一度に変更する必要がある場合は、

  • DataFrame.set_axis()メソッドaxis=1。リストのようなシーケンスを渡します。インプレース変更のオプションも利用できます。

renameaxis=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 各列に対して一度呼び出されるコールバックも受け入れます。

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

replacePythonの文字列のメソッドと同様に、pandas IndexとSeries(オブジェクト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_axisaxis=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/4909087set_axisは、メソッドをチェーンしようとするときに役立ちます。

比較する

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

前者はより自然で自由に流れる構文です。


3

パンダの特定の列の名前を変更するには、少なくとも5つの方法があります。以下に、元の回答へのリンクとともにそれらをリストしました。また、これらのメソッドの時間を測定したところ、ほぼ同じように動作することがわかりました(ただし、YMMVはデータセットとシナリオによって異なります)。以下のテストケースは、100万行を含む列を持つデータフレームで列の名前を変更するA M N Zことです。A2 M2 N2 Z2AZ

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

出力:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

最も直感的で、アプリケーションに実装しやすい方法を使用してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.