Satu jalur atau solusi Pipeline
Saya akan fokus pada dua hal:
OP dengan jelas menyatakan
Saya memiliki nama kolom yang diedit menyimpannya dalam daftar, tetapi saya tidak tahu bagaimana cara mengganti nama kolom.
Saya tidak ingin menyelesaikan masalah tentang cara mengganti '$'atau menghapus karakter pertama dari setiap tajuk kolom. OP telah melakukan langkah ini. Alih-alih saya ingin fokus mengganti columnsobjek yang ada dengan yang baru diberi daftar nama kolom pengganti.
df.columns = newdi mana newdaftar nama kolom baru sesederhana yang didapatnya. Kekurangan dari pendekatan ini adalah bahwa itu memerlukan pengeditan columnsatribut dataframe yang ada dan tidak dilakukan inline. Saya akan menunjukkan beberapa cara untuk melakukan ini melalui pipelining tanpa mengedit kerangka data yang ada.
Setup 1
Untuk fokus pada kebutuhan untuk mengganti nama ganti nama kolom dengan daftar yang sudah ada sebelumnya, saya akan membuat contoh dataframe baru dfdengan nama kolom awal dan nama kolom baru yang tidak terkait.
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
Solusi 1
pd.DataFrame.rename
Sudah dikatakan bahwa jika Anda memiliki kamus yang memetakan nama kolom lama ke nama kolom baru, Anda dapat menggunakan 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
Namun, Anda dapat dengan mudah membuat kamus itu dan memasukkannya ke dalam panggilan ke rename. Berikut ini mengambil keuntungan dari fakta bahwa ketika mengulangi df, kami mengulangi setiap nama kolom.
# 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
Ini berfungsi baik jika nama kolom asli Anda unik. Tetapi jika tidak, maka ini rusak.
Setup 2
kolom non-unik
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
Solusi 2
pd.concat menggunakan keysargumen
Pertama, perhatikan apa yang terjadi ketika kami mencoba menggunakan solusi 1:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
Kami tidak memetakan newdaftar sebagai nama kolom. Kami akhirnya mengulangi y765. Sebagai gantinya, kita bisa menggunakan keysargumen pd.concatfungsi sambil mengulangi melalui kolom df.
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
Solusi 3
Rekonstruksi. Ini seharusnya hanya digunakan jika Anda memiliki satu dtypeuntuk semua kolom. Jika tidak, Anda akan mendapatkan dtype objectsemua kolom dan mengonversinya kembali memerlukan lebih banyak pekerjaan kamus.
Tunggal dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
Campuran 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
Solusi 4
Ini adalah trik menarik perhatian dengan transposedan set_index. pd.DataFrame.set_indexmemungkinkan kita untuk mengatur inline indeks tetapi tidak ada yang sesuai set_columns. Jadi kita bisa memindahkan, lalu set_index, dan memindahkan kembali. Namun, peringatan tunggal dtypeversus campuran yang sama dtypedari solusi 3 berlaku di sini.
Tunggal dtype
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
Campuran 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
Solusi 5
Gunakan a lambdadalam pd.DataFrame.renamesiklus itu melalui setiap elemen new
Dalam solusi ini, kami melewati lambda yang mengambil xtetapi kemudian mengabaikannya. Ini juga membutuhkan ytetapi tidak mengharapkannya. Sebagai gantinya, sebuah iterator diberikan sebagai nilai default dan saya kemudian dapat menggunakannya untuk menggilir satu per satu tanpa memperhatikan apa nilainya x.
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
Dan seperti yang ditunjukkan kepada saya oleh orang-orang di obrolan sopython , jika saya menambahkan *di antaranya xdan y, saya dapat melindungi yvariabel saya . Padahal, dalam konteks ini saya tidak percaya itu perlu dilindungi. Masih layak disebut.
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6