web-dev-qa-db-ja.com

パンダの列名の変更

元の列ラベルを置き換えるために編集する必要があるパンダと列ラベルを使用するDataFrameがあります。

元の列名が次のようになっているDataFrame Aの列名を変更します。

['$a', '$b', '$c', '$d', '$e'] 

['a', 'b', 'c', 'd', 'e'].

編集した列名をリストに格納しましたが、列名を置き換える方法がわかりません。

1379
user1504276

それを.columns属性に割り当てるだけです。

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
1428
eumiro

df.rename() 関数を使用して、名前を変更する列を参照してください。すべての列の名前を変更する必要はありません。

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)
2257
lexual

rename メソッドは関数を取ることができます。例えば:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)
344
Andy Hayden

http://pandas.pydata.org/pandas-docs/stable/text.html に記載されているように:

df.columns = df.columns.str.replace('$','')
150
kadee

パンダ0.21 +回答

バージョン0.21では、列名の変更に対していくつかの重要な更新が行われました。

  • renameメソッドaxisまたは1に設定できるcolumnsパラメータを追加しました。このアップデートにより、このメソッドは他のパンダAPIと一致するようになります。それはまだindexcolumnsパラメータを持っています、しかしあなたはもはやそれらを使うことを強制されません。
  • inplaceFalseに設定した set_axisメソッド を使用すると、すべてのインデックスまたは列ラベルの名前をリストで変更できます。

Pandas 0.21+の例

サンプルDataFrameを作成します。

df = pd.DataFrame({'$a':[1,2], '$b': [3,4], 
                   '$c':[5,6], '$d':[7,8], 
                   '$e':[9,10]})

   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

renameaxis='columns'またはaxis=1と一緒に使用する

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')

または

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)

どちらも次のようになります。

   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10

古いメソッドシグネチャを使用することも可能です。

df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})

rename関数は、各列名に適用される関数も受け入れます。

df.rename(lambda x: x[1:], axis='columns')

または

df.rename(lambda x: x[1:], axis=1)

リストとset_axisinplace=Falseを使う

set_axisメソッドに、列数(またはインデックス)の長さと同じ長さのリストを指定することができます。現在、inplaceのデフォルトはTrueですが、将来のリリースではinplaceがデフォルトでFalseになります。

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)

または

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)

なぜdf.columns = ['a', 'b', 'c', 'd', 'e']を使わないのですか?

このように列を直接代入しても問題ありません。それは完全に良い解決策です。

set_axisを使用する利点は、メソッドチェーンの一部として使用できることと、DataFrameの新しいコピーを返すことです。それがなければ、列を再割り当てする前に、チェーンの中間ステップを別の変数に格納する必要があります。

# 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()
149
Ted Petrou

すべての列名の$記号を削除したいだけなので、次のようにします。

df = df.rename(columns=lambda x: x.replace('$', ''))

OR

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
124
paulo.filip3
df.columns = ['a', 'b', 'c', 'd', 'e']

指定した順序で、既存の名前が指定した名前に置き換えられます。

71
M PAUL
old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(Zip(old_names, new_names)), inplace=True)

こうすれば手動でnew_namesを好きなように編集できます。つづりの誤り、アクセントの修正、特殊文字の削除などのために数桁だけ名前を変更する必要がある場合に最適です。

56
migloo

私はこの方法が便利だと思います。

df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})

この方法では、列名を個別に変更できます。

48
wolfog

列名とシリーズ名

舞台裏で何が起こるのか、少し説明したいと思います。

データフレームは一連のシリーズです。

シリーズはnumpy.arrayの拡張です。

numpy.arraysはプロパティ.nameを持っています

これはシリーズの名前です。パンダがこの属性を尊重することはめったにありませんが、それは適所にとどまり、いくつかのパンダの振る舞いをハッキングするために使用することができます。

列リストの命名

df.columns属性が実際にはlistなのにSeriesであることについて、ここでの多くの回答が話しています。これは.name属性があることを意味します。

これが、カラムの名前Seriesを埋めることにした場合に起こります。

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3

インデックスの名前は常に1列下にくることに注意してください。

残る遺物

.name属性は時々残る。 df.columns = ['one', 'two']を設定した場合、df.one.name'one'になります。

df.one.name = 'three'を設定した場合、df.columns['one', 'two']を与え、df.one.name'three'を与えます。

しかし

pd.DataFrame(df.one)が戻ります

    three
0       1
1       2
2       3

なぜならパンダは既に定義されているSeries.nameを再利用するからです。

マルチレベル列名

Pandasには、多層の列名を付ける方法があります。それほど多くの魔法は関与していません、しかし、私は誰もこれをここで拾っているのを見ないので私も私の答えでこれをカバーしたかったです。

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |

これは、次のように列をリストに設定することで簡単に達成できます。

df.columns = [['one', 'one'], ['one', 'two']]
33
firelynx

ワンラインまたはパイプラインソリューション

2つのことに焦点を当てます。

  1. OPは明確に述べています

    編集した列名をリストに格納しましたが、列名を置き換える方法がわかりません。

    '$'を置き換える方法や、各列ヘッダーから最初の文字を削除する方法の問題は解決したくありません。 OPはすでにこのステップを実行しています。代わりに、既存のcolumnsオブジェクトを、置換列名のリストが与えられた新しいオブジェクトで置き換えることに集中したいです。

  2. newが新しい列の名前のリストであるdf.columns = newは、それが得るのと同じくらい簡単です。このアプローチの欠点は、既存のデータフレームのcolumns属性を編集する必要があり、インラインで行われないことです。既存のデータフレームを編集せずにパイプラインでこれを実行する方法をいくつか紹介します。


設定1
置換列の名前を既存のリストに変更する必要性に焦点を当てるために、最初の列名と無関係の新しい列名を使用して、新しいサンプルデータフレームdfを作成します。

df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']

df

   Jack  Mahesh  Xin
0     1       3    5
1     2       4    6

解決策1
pd.DataFrame.rename

古い列名を新しい列名にマッピングする辞書がある場合は、pd.DataFrame.renameを使用できます。

d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)

   x098  y765  z432
0     1     3     5
1     2     4     6

ただし、その辞書を簡単に作成してrenameの呼び出しに含めることができます。以下は、dfを反復処理するときに、各列名を反復処理するという事実を利用しています。

# given just a list of new column names
df.rename(columns=dict(Zip(df, new)))

   x098  y765  z432
0     1     3     5
1     2     4     6

元の列名が一意の場合、これは非常に効果的です。しかし、そうでなければ、これは破綻します。


設定2
非固有の列

df = pd.DataFrame(
    [[1, 3, 5], [2, 4, 6]],
    columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']

df

   Mahesh  Mahesh  Xin
0       1       3    5
1       2       4    6

解決策2
pd.concatkeys引数の使用

まず、解決策1を使用しようとしたときに何が起こるかに注意してください。

df.rename(columns=dict(Zip(df, new)))

   y765  y765  z432
0     1     3     5
1     2     4     6

newリストを列名としてマッピングしませんでした。私たちはy765を繰り返すことになりました。代わりに、keysの列を反復処理しながら、pd.concat関数のdf引数を使用できます。

pd.concat([c for _, c in df.items()], axis=1, keys=new) 

   x098  y765  z432
0     1     3     5
1     2     4     6

解決策3
再構築します。これは、すべての列にdtypeが1つある場合にのみ使用してください。それ以外の場合は、すべての列に対してdtypeobjectが生成され、それらを元に戻すにはさらに辞書作業が必要になります。

シングルdtype

pd.DataFrame(df.values, df.index, new)

   x098  y765  z432
0     1     3     5
1     2     4     6

混合dtype

pd.DataFrame(df.values, df.index, new).astype(dict(Zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

解決策4
これはtransposeset_indexに関する奇妙なトリックです。 pd.DataFrame.set_index を使用すると、インデックスをインラインで設定できますが、対応するset_columnsはありません。それで、転置して、次にset_index、そして転置することができます。ただし、解決策3のdtypedtypeが混在している場合の同じ警告がここでも適用されます。

シングルdtype

df.T.set_index(np.asarray(new)).T

   x098  y765  z432
0     1     3     5
1     2     4     6

混合dtype

df.T.set_index(np.asarray(new)).T.astype(dict(Zip(new, df.dtypes)))

   x098  y765  z432
0     1     3     5
1     2     4     6

解決策5
lambdaの各要素を循環するpd.DataFrame.renamenewを使用します
この解決法では、xを取るがそれを無視するラムダを渡します。それはyも取りますが、それを期待していません。代わりに、イテレータがデフォルト値として与えられているので、xの値が何であるかに関係なく、それを使用して一度に1つずつ循環することができます。

df.rename(columns=lambda x, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

そして、sopython chatの人々が私に指摘したように、xyの間に*を追加すれば、y変数を保護できます。しかし、この文脈では私はそれが保護する必要があるとは思わない。それはまだ言及する価値があります。

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6
32
piRSquared

df = df.rename(columns=lambda n: n.replace('$', ''))はこれを解決する機能的な方法です

16
lf2225
df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

新しい列のリストが既存の列と同じ順序である場合、割り当ては簡単です。

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1

古い列名を新しい列名にキー入力する辞書がある場合は、次のようにします。

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1

リストや辞書のマッピングがない場合は、リスト内包表記によって先頭の$記号を削除できます。

df.columns = [col[1:] if col[0] == '$' else col for col in df]
16
Alexander

あなたがデータフレームを持っているならば、df.columnsはあなたが操作することができるリストにすべてをダンプし、そして列の名前としてあなたのデータフレームに再割り当てします...

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(Zip(columns, things)), inplace=True)
df.head() #to validate the output

最良の方法? IDK道 - はい。

質問に対する回答で提示されたすべての主なテクニックを評価するためのより良い方法は、メモリと実行時間を測定するためにcProfileを使用することです。 @kadee、@ kaitlyn、および@eumiroは、実行時間が最も早い関数です。これらの関数は非常に高速ですが、すべての回答について.000秒と.001秒の丸めを比較しています。道徳的:上記の私の答えはおそらく「最善」の方法ではありません。

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(Zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(Zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')
15
andrewwowens
14
Yog

元の列ラベルを置き換えることができるもう1つの方法は、元の列ラベルから不要な文字(ここでは '$')を削除することです。

これは、df.columnsに対してforループを実行し、削除された列をdf.columnsに追加することによって実行できました。

代わりに、以下のようなリスト内包表記を使用して、これを単一のステートメントできちんと実行できます。

df.columns = [col.strip('$') for col in df.columns]

(Pythonのstripメソッドは文字列の最初と最後から与えられた文字を取り除きます。)

11
kait

私はこの質問と答えが死に噛んだことを知っています。しかし、私はそれが私が抱えていた問題の一つのためのインスピレーションのためにそれを参照しました。私は異なった答えからの小片を使ってそれを解決することができました、それで誰かがそれを必要とする場合に備えて私の応答を提供します。

私の方法は一般的なもので、ここでdelimiters=変数をカンマで区切って追加の区切り文字を追加し、それを将来に対して保証することができます。

作業コード:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

出力:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
10
Anil_M

本当にシンプルで使いやすい

df.columns = ['Name1', 'Name2', 'Name3'...]

そしてそれはあなたがそれらを置いた順序でカラム名を割り当てます

9
Thodoris P

そのために str.slice を使うことができます。

df.columns = df.columns.str.slice(1)
9

データフレーム列の名前を変更してフォーマットを置換する

import pandas as pd

data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975],
        'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'],
        }
df = pd.DataFrame(data)

#Rename Columns
df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True)

#Replace format
df = df.columns.str.replace(' ', '_')
8
Sankar guru

これらのアプローチはMultiIndexには機能しないことに注意してください。 MultiIndexの場合は、次のようにする必要があります。

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6
7
oxer

データフレームの読み取り中に列名を変更する

>>> df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1]}).rename(columns = 
         {'$a' : 'a','$b':'b','$c':'c'})

Out[1]: 
   a  b  c
0  1  1  1
7
dimension

もう1つの選択肢は、正規表現を使用して名前を変更することです。

import pandas as pd
import re

df = pd.DataFrame({'$a':[1,2], '$b':[3,4], '$c':[5,6]})

df = df.rename(columns=lambda x: re.sub('\$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6
7
sbha

これはおそらく問題に対する最も簡単な解決策です。それがどのように機能するかについては、非常に自明です。

import pandas as pd

df.columns = [['$a', '$b', '$c', '$d', '$e']]
df.rename(columns = {'$a':'a','$b':'b','$c':'c','$d':'d','$e':'e'})

df.head()
6
goaty

データフレームの作成に役立つライブラリをインポートします。

import pandas as pd
import numpy as np

データフレームを作成します。

df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])

データフレーム名の変更

df.rename(columns={'a':'x', 'b':'y', 'c':'z'}, index=str)

df.columnsは異なる値になるはずです

5
Nitish Gaddam

私は3つの簡単な方法を見ます

df.columns

出力:['$ a'、 '$ b'、 '$ c'、 '$ d'、 '$ e']

1。

df.columns = ['a', 'b', 'c', 'd', 'e']

2。

df.columns = df.columns.str.replace('$','')

3。

df.rename(columns={'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e' : 'e'}, inplace=True)

4
Nursnaaz

提供システムによって指定された大量の列を自分の制御の及ばない範囲で処理する必要がある場合は、一般的な方法と特定の置換方法を組み合わせた次の方法を思いつきました。

最初に正規表現を使用してデータフレームの列名からディクショナリを作成して列名の特定の付録を破棄し、次に受信側データベースで後で予想されるように特定の置換をディクショナリに追加してコア列に名前を付けます。

これは一度にデータフレームに適用されます。

dict=dict(Zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)
4
matthhias

これを試して。わたしにはできる

df.rename(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})

df.columns = ['a', 'b',index=False]という行名が欲しくない場合

3
Domnick

これは私がタイピングを減らすために使うのが好きな気の利いた小さな関数です:

def rename(data, oldnames, newname): 
    if type(oldnames) == str: #input can be a string or list of strings 
        oldnames = [oldnames] #when renaming multiple columns 
        newname = [newname] #make sure you pass the corresponding list of new names
    i = 0 
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0: 
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: #doesn't have to be an exact match 
            print("Found multiple columns that matched " + str(name) + " :")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1 
    return data   

これがどのように機能するかの例は、次のとおりです。

In [2]: df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['col1','col2','omg','idk'])
#first list = existing variables
#second list = new names for those variables
In [3]: df = rename(df, ['col','omg'],['first','ohmy']) 
Found multiple columns that matched col :
0: col1
1: col2

please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')
2
seeiespi

正規表現が使えると仮定します。この解決法は正規表現を使った手動エンコーディングの必要性を取り除きます

import pandas as pd
import re

srch=re.compile(r"\w+")

data=pd.read_csv("CSV_FILE.csv")
cols=data.columns
new_cols=list(map(lambda v:v.group(),(list(map(srch.search,cols)))))
data.columns=new_cols
1
Kaustubh J
import pandas as pd

data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975],
        'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'],
        }
df = pd.DataFrame(data)

#Rename Columns
df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True)

#Replace format
df.columns = df.columns.str.replace(' ', '_')
1
Amita Rawat

これがあなたのデータフレームだとしましょう。

enter image description here

2つの方法を使用して、列の名前を変更できます。

  1. Dataframe.columns = [#list]を使用する

    df.columns = ['a'、 'b'、 'c'、 'd'、 'e']

enter image description here

このメソッドの制限は、1つの列を変更する必要がある場合、完全な列リストを渡す必要があることです。また、このメソッドはインデックスラベルには適用できません。たとえば、これを渡した場合:

df.columns = ['a','b','c','d']

これによりエラーがスローされます。長さの不一致:予想される軸には5つの要素があり、新しい値には4つの要素があります。

  1. 別のメソッドはPandas rename()メソッドで、これを使用してインデックス、列、または行の名前を変更します

    df = df.rename(columns = {'$ a': 'a'})

enter image description here

同様に、任意の行または列を変更できます。

0
vibhu_singh