Ganti nama kolom tertentu dalam panda

182

Saya punya kerangka data yang disebut data. Bagaimana saya mengganti nama satu-satunya tajuk kolom? Misalnya gdpuntuk 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
natsuki_2002
sumber
7
Jelas ada tumpang tindih, tetapi bagi saya tidak jelas dari "Mengganti nama kolom dalam panda" bahwa Anda dapat memilih elemen kolom soliter untuk mengganti nama. Tentu saja, dalam retrospeksi itu sudah jelas, dan jika saya menggali lebih dalam, saya mungkin akan mengetahuinya, tetapi saya pikir pertanyaan / jawaban ini lebih baik untuk menunjukkan hal itu.
jeremiahbuddha

Jawaban:

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

The renamemenunjukkan bahwa ia menerima sebuah dict sebagai param untuk columnssehingga Anda hanya lulus dict dengan satu entri.

Lihat juga terkait

EdChum
sumber
3
Ini membutuhkan waktu yang sangat lama pada kerangka data yang besar, jadi saya percaya ini apakah semacam menyalin seluruh kerangka data dalam memori?
elgehelge
1
@elgehelge seharusnya tidak dilakukan, sebagian besar operasi panda akan mengembalikan salinan dan beberapa menerima inplaceparam, jika mengabaikan param ini maka ini adalah bug, dapatkah Anda melakukan pengaturan waktu dengan dan tanpa param, juga mencoba sesuatu seperti new_df = df.rename(columns={'new_name':'old_name'})dan melihat apakah ini lebih cepat atau tidak
EdChum
1
@ EdChum Terima kasih. Menghapus inplaceparam hampir menggandakan waktu dari 14 detik menjadi 26 detik. Namun 14 detik masih cukup lama hanya untuk mengganti header ..
elgehelge
2
hanya satu catatan, waspadalah! jika kolom target tidak ada, (salah mengeja nama atau lebih) ini tidak akan melakukan apa-apa tanpa kesalahan atau peringatan.
Amir
1
@ Quastiat agak menyedihkan mengapa beberapa dari operasi sederhana ini lebih cepat dengan melakukan pemahaman daftar. Meskipun pada dasarnya kecuali jika Anda memiliki df yang sangat besar, maka itu seharusnya tidak terlalu penting kecuali jika Anda mengganti nama banyak kolom pada df besar
EdChum
27

Implementasi yang jauh lebih cepat adalah menggunakan list-comprehensionjika Anda perlu mengganti nama satu kolom.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Jika diperlukan untuk mengganti nama beberapa kolom, gunakan ekspresi kondisional seperti:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Atau, buat pemetaan menggunakan dictionarydan jalankan operasi list-comprehensiondengan itu getdengan menetapkan nilai default sebagai nama lama:

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]

Pengaturan waktu:

%%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
Nickil Maveli
sumber
Saya ingin menggunakan metode ini, tetapi sayangnya tidak berhasil pd.merge_asof()karena ini adalah ekspresi :(.
thdoan
14

Bagaimana cara mengganti nama kolom tertentu dalam panda?

Dari v0.24 +, untuk mengganti nama satu (atau lebih) kolom sekaligus,

Jika Anda perlu mengganti nama SEMUA kolom sekaligus,

  • DataFrame.set_axis()metode dengan axis=1. Lewati urutan seperti daftar. Opsi juga tersedia untuk modifikasi di tempat.

rename dengan 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

Dengan 0.21+, Anda sekarang dapat menentukan axisparameter dengan 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

(Catatan yang renametidak ada di tempat secara default, jadi Anda harus menetapkan kembali hasilnya .)

Penambahan ini telah dibuat untuk meningkatkan konsistensi dengan sisa API. axisArgumen baru ini analog dengan columnsparameter — mereka melakukan hal yang sama.

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 juga menerima panggilan balik yang dipanggil satu kali untuk setiap kolom.

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

Untuk skenario khusus ini, Anda ingin menggunakannya

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Mirip dengan replacemetode string dalam python, panda Indeks dan Seri (objek dtype saja) mendefinisikan metode ("vectorized") str.replaceuntuk string dan penggantian berbasis regex.

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

Keuntungannya dibandingkan metode lain adalah str.replacemendukung regex (diaktifkan secara default). Lihat dokumen untuk informasi lebih lanjut.


Melewati daftar set_axisdenganaxis=1

Panggil set_axisdengan daftar tajuk. Panjang daftar harus sama dengan kolom / ukuran indeks. set_axisbermutasi DataFrame asli secara default, tetapi Anda dapat menentukan inplace=Falseuntuk mengembalikan salinan yang dimodifikasi.

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

Catatan: Dalam rilis mendatang, inplaceakan default ke True.

Metode Chaining
Mengapa memilih set_axisketika kita sudah memiliki cara yang efisien dalam menentukan kolom df.columns = ...? Seperti yang ditunjukkan oleh Ted Petrou dalam [jawaban ini], ( https://stackoverflow.com/a/46912050/4909087 ) set_axisberguna saat mencoba metode berantai.

Membandingkan

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

Melawan

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

Yang pertama adalah sintaksis yang lebih alami dan mengalir bebas.

cs95
sumber
3

Setidaknya ada lima cara berbeda untuk mengganti nama kolom tertentu dalam panda, dan saya telah mendaftarkannya di bawah ini bersama dengan tautan ke jawaban asli. Saya juga menghitung waktu metode ini dan menemukan mereka melakukan hampir sama (meskipun YMMV tergantung pada set data dan skenario Anda). Kasus uji di bawah ini adalah untuk mengubah nama kolom A M N Zuntuk A2 M2 N2 Z2di dataframe dengan kolom Auntuk Zmengandung satu juta baris.

# 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))

Keluaran:

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

Gunakan metode yang paling intuitif untuk Anda dan paling mudah untuk Anda terapkan dalam aplikasi Anda.

Terima kasih
sumber