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 columns
objek yang ada dengan yang baru diberi daftar nama kolom pengganti.
df.columns = new
di mana new
daftar nama kolom baru sesederhana yang didapatnya. Kekurangan dari pendekatan ini adalah bahwa itu memerlukan pengeditan columns
atribut 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 df
dengan 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 keys
argumen
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 new
daftar sebagai nama kolom. Kami akhirnya mengulangi y765
. Sebagai gantinya, kita bisa menggunakan keys
argumen pd.concat
fungsi 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 dtype
untuk semua kolom. Jika tidak, Anda akan mendapatkan dtype
object
semua 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 transpose
dan set_index
. pd.DataFrame.set_index
memungkinkan 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 dtype
versus campuran yang sama dtype
dari 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 lambda
dalam pd.DataFrame.rename
siklus itu melalui setiap elemen new
Dalam solusi ini, kami melewati lambda yang mengambil x
tetapi kemudian mengabaikannya. Ini juga membutuhkan y
tetapi 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 x
dan y
, saya dapat melindungi y
variabel 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