Ubah nama Indeks Pandas DataFrame

151

Saya memiliki file csv tanpa header, dengan indeks DateTime. Saya ingin mengganti nama indeks dan nama kolom, tetapi dengan df.rename () hanya nama kolom yang diganti. Bug? Saya menggunakan versi 0.12.0

In [2]: df = pd.read_csv(r'D:\Data\DataTimeSeries_csv//seriesSM.csv', header=None, parse_dates=[[0]], index_col=[0] )

In [3]: df.head()
Out[3]: 
                   1
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667

In [4]: df.rename(index={0:'Date'}, columns={1:'SM'}, inplace=True)

In [5]: df.head()
Out[5]: 
                  SM
0                   
2002-06-18  0.112000
2002-06-22  0.190333
2002-06-26  0.134000
2002-06-30  0.093000
2002-07-04  0.098667
Mattijn
sumber
5
Bagi mereka yang datang ke pertanyaan ini pada tahun 2017, periksa jawaban di bawah ini untuk melihat penjelasan rename_axismetode yang sangat rinci .
Ted Petrou
3
Dan bagi mereka yang tidak mau repot membaca seluruh jawaban bagus di bawah ini, maka solusi cepatnya adalah df.rename_axis("Date", axis='index', inplace=True)sesuai dokumentasi pandas.pydata.org/pandas-docs/stable/generated/… ataudf.index.names = ['Date']
tommy.carstensen

Jawaban:

253

The renameMetode mengambil kamus untuk indeks yang berlaku untuk indeks nilai-nilai .
Anda ingin mengganti nama menjadi nama tingkat indeks:

df.index.names = ['Date']

Cara yang baik untuk memikirkan hal ini adalah bahwa kolom dan indeks adalah jenis objek ( Indexatau MultiIndex) yang sama, dan Anda dapat menukar keduanya melalui transpose.

Ini agak membingungkan karena nama indeks memiliki arti yang mirip dengan kolom, jadi berikut ini beberapa contohnya:

In [1]: df = pd.DataFrame([[1, 2, 3], [4, 5 ,6]], columns=list('ABC'))

In [2]: df
Out[2]: 
   A  B  C
0  1  2  3
1  4  5  6

In [3]: df1 = df.set_index('A')

In [4]: df1
Out[4]: 
   B  C
A      
1  2  3
4  5  6

Anda dapat melihat perubahan nama pada indeks, yang dapat mengubah nilai 1:

In [5]: df1.rename(index={1: 'a'})
Out[5]: 
   B  C
A      
a  2  3
4  5  6

In [6]: df1.rename(columns={'B': 'BB'})
Out[6]: 
   BB  C
A       
1   2  3
4   5  6

Saat mengganti nama level:

In [7]: df1.index.names = ['index']
        df1.columns.names = ['column']

Catatan: atribut ini hanyalah sebuah daftar, dan Anda dapat melakukan penggantian nama sebagai pemahaman / peta daftar.

In [8]: df1
Out[8]: 
column  B  C
index       
1       2  3
4       5  6
Andy Hayden
sumber
4
Jawaban yang bagus. Hanya pengingat lembut bahwa tanpa "inplace =True", df1.renametidak akan benar-benar mengubah apa pun.
Sarah
70

Jawaban yang dipilih saat ini tidak menyebutkan rename_axismetode yang dapat digunakan untuk mengganti nama indeks dan tingkat kolom.


Panda memiliki beberapa keanehan dalam hal mengganti nama level indeks. Ada juga metode DataFrame baru yang rename_axistersedia untuk mengubah nama tingkat indeks.

Mari kita lihat DataFrame

df = pd.DataFrame({'age':[30, 2, 12],
                       'color':['blue', 'green', 'red'],
                       'food':['Steak', 'Lamb', 'Mango'],
                       'height':[165, 70, 120],
                       'score':[4.6, 8.3, 9.0],
                       'state':['NY', 'TX', 'FL']},
                       index = ['Jane', 'Nick', 'Aaron'])

masukkan deskripsi gambar di sini

DataFrame ini memiliki satu level untuk setiap indeks baris dan kolom. Baik indeks baris dan kolom tidak memiliki nama. Mari kita ubah nama tingkat indeks baris menjadi 'nama'.

df.rename_axis('names')

masukkan deskripsi gambar di sini

The rename_axisMetode juga memiliki kemampuan untuk mengubah nama tingkat kolom dengan mengubah axisparameter:

df.rename_axis('names').rename_axis('attributes', axis='columns')

masukkan deskripsi gambar di sini

Jika Anda mengatur indeks dengan beberapa kolom, maka nama kolom akan menjadi nama level indeks baru. Mari tambahkan ke tingkat indeks ke DataFrame asli kita:

df1 = df.set_index(['state', 'color'], append=True)
df1

masukkan deskripsi gambar di sini

Perhatikan bagaimana indeks asli tidak memiliki nama. Kita masih dapat menggunakan rename_axistetapi harus mengirimkannya daftar dengan panjang yang sama dengan jumlah level indeks.

df1.rename_axis(['names', None, 'Colors'])

masukkan deskripsi gambar di sini

Anda dapat menggunakan Noneuntuk menghapus nama tingkat indeks secara efektif.


Seri bekerja sama tetapi dengan beberapa perbedaan

Mari buat Seri dengan tiga level indeks

s = df.set_index(['state', 'color'], append=True)['food']
s

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: food, dtype: object

Kita dapat menggunakan rename_axisserupa dengan yang kita lakukan dengan DataFrames

s.rename_axis(['Names','States','Colors'])

Names  States  Colors
Jane   NY      blue      Steak
Nick   TX      green      Lamb
Aaron  FL      red       Mango
Name: food, dtype: object

Perhatikan bahwa ada bagian ekstra dari metadata di bawah Seri yang dipanggil Name. Saat membuat Series dari DataFrame, atribut ini disetel ke nama kolom.

Kita bisa memberikan nama string ke renamemetode untuk mengubahnya

s.rename('FOOOOOD')

       state  color
Jane   NY     blue     Steak
Nick   TX     green     Lamb
Aaron  FL     red      Mango
Name: FOOOOOD, dtype: object

DataFrames tidak memiliki atribut ini dan faktanya akan memunculkan pengecualian jika digunakan seperti ini

df.rename('my dataframe')
TypeError: 'str' object is not callable

Sebelum pandas 0.21, Anda dapat menggunakan rename_axisuntuk mengganti nama nilai di indeks dan kolom. Sudah usang, jadi jangan lakukan ini

Ted Petrou
sumber
1
Haruskah Anda bertukar df1 = df.set_index(['state', 'color'], append=True)dengan df1.rename_axis(['names', None, 'Colors'])?
salhin
Bagaimana jika saya ingin mengganti nama "Nick" menjadi "Nicolas"? Itulah yang saya cari ketika saya mencari "ganti nama indeks pandas" di Google dan berakhir di sini. EDIT: Oh tunggu, jawaban yang diterima menjelaskan itu, pada awalnya tidak jelas bagi saya.
Ben Farmer
Bagus, ini adalah satu-satunya jawaban yang dapat digunakan dalam tugas yang dirantai!
IanS
20

Untuk pandasversi yang lebih baru

df.index = df.index.rename('new name')

atau

df.index.rename('new name', inplace=True)

Yang terakhir diperlukan jika bingkai data harus mempertahankan semua propertinya.

Serge Stroobandt
sumber
18

Dalam Pandas versi 0.13 dan yang lebih baru, nama tingkat indeks tidak dapat diubah (jenis FrozenList) dan tidak dapat lagi disetel secara langsung. Anda harus terlebih dahulu menggunakan Index.rename()untuk menerapkan nama tingkat indeks baru ke Indeks dan kemudian menggunakan DataFrame.reindex()untuk menerapkan indeks baru ke DataFrame. Contoh:

Untuk versi Pandas <0.13

df.index.names = ['Date']

Untuk versi Pandas> = 0.13

df = df.reindex(df.index.rename(['Date']))
David Smith
sumber
9
Tidak benar! Dalam versi saya Pandas (0.13.1) df.index.names = ['foo'] berfungsi dengan baik!
LondonRob
5
Terima kasih telah memperhatikan bahwa @LondonRob - `df.index.names = ['foo']` juga berfungsi untuk saya dengan Pandas 0.14. Ternyata itu hanya rusak sebentar dan dimasukkan saat saya mengujinya.
David Smith
1
Menetapkan nama untuk salah satu indexatau columnsecara langsung mengubah keduanya untuk saya (di Pandas 0.19), tetapi tidak dengan metode ini.
FooBar
8

Anda juga dapat menggunakan Index.set_namessebagai berikut:

In [25]: x = pd.DataFrame({'year':[1,1,1,1,2,2,2,2],
   ....:                   'country':['A','A','B','B','A','A','B','B'],
   ....:                   'prod':[1,2,1,2,1,2,1,2],
   ....:                   'val':[10,20,15,25,20,30,25,35]})

In [26]: x = x.set_index(['year','country','prod']).squeeze()

In [27]: x
Out[27]: 
year  country  prod
1     A        1       10
               2       20
      B        1       15
               2       25
2     A        1       20
               2       30
      B        1       25
               2       35
Name: val, dtype: int64
In [28]: x.index = x.index.set_names('foo', level=1)

In [29]: x
Out[29]: 
year  foo  prod
1     A    1       10
           2       20
      B    1       15
           2       25
2     A    1       20
           2       30
      B    1       25
           2       35
Name: val, dtype: int64
LondonRob
sumber
2
Bisakah ini bekerja untuk multiIndex? MultiIndex(levels=[['A', 'B', 'C', 'D', 'E', 'F'], ['Y', 'Z']], labels=[[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]], names=['Portfolio', None])Apakah mungkin untuk mengganti nama Nonemenjadi measures?
ctrl-alt-delete
2

Jika Anda ingin menggunakan pemetaan yang sama untuk mengganti nama kolom dan indeks, Anda dapat melakukan:

mapping = {0:'Date', 1:'SM'}
df.index.names = list(map(lambda name: mapping.get(name, name), df.index.names))
df.rename(columns=mapping, inplace=True)
danio
sumber
2
df.index.rename('new name', inplace=True)

Apakah satu-satunya yang melakukan pekerjaan untuk saya (panda 0.22.0).
Tanpa inplace = True, nama indeks tidak disetel dalam kasus saya.

Jan H.
sumber
2

Untuk Indeks Tunggal:

 df.index.rename('new_name')

Untuk Multi Indeks:

 df.index.rename(['new_name','new_name2'])

KAMI juga dapat menggunakan ini di panda terbaru:

rename_axis

Abhishek Sengupta
sumber
Jika Anda melakukan itu, Anda hanya akan memiliki indeks yang diganti namanya sebagai pengembalian tetapi bingkai data tidak akan diubah.
Jean Paul
1

Anda dapat menggunakan indexdan columnsatribut pandas.DataFrame. CATATAN: jumlah elemen daftar harus sesuai dengan jumlah baris / kolom.

#       A   B   C
# ONE   11  12  13
# TWO   21  22  23
# THREE 31  32  33

df.index = [1, 2, 3]
df.columns = ['a', 'b', 'c']
print(df)

#     a   b   c
# 1  11  12  13
# 2  21  22  23
# 3  31  32  33
nucsit026
sumber