Saya memiliki kamus yang terlihat seperti ini: di = {1: "A", 2: "B"}
Saya ingin menerapkannya pada kolom "col1" dari dataframe yang mirip dengan:
col1 col2
0 w a
1 1 2
2 2 NaN
mendapatkan:
col1 col2
0 w a
1 A 2
2 B NaN
Bagaimana saya bisa melakukan ini? Untuk beberapa alasan, istilah googling yang berkaitan dengan ini hanya menunjukkan kepada saya tautan tentang cara membuat kolom dari dicts dan sebaliknya: - /
python
dictionary
pandas
remap
TheChymera
sumber
sumber
col```` is tuple. The error info is
Tidak dapat membandingkan jenis 'ndarray (dtype = objek)' dan 'tuple'```'3.6.1 |Anaconda custom (64-bit)| (default, May 11 2017, 13:25:24) [MSC v.1900 64 bit (AMD64)]'
map
bisa jauh lebih cepat daripadareplace
Jika kamus Anda memiliki lebih dari beberapa kunci, menggunakan
map
bisa jauh lebih cepat daripadareplace
. Ada dua versi dari pendekatan ini, tergantung pada apakah kamus Anda secara mendalam memetakan semua nilai yang mungkin (dan juga apakah Anda ingin yang tidak cocok mempertahankan nilainya atau dikonversi ke NaNs):Pemetaan Lengkap
Dalam hal ini, formulirnya sangat sederhana:
Meskipun
map
paling umum mengambil fungsi sebagai argumennya, ia dapat juga mengambil kamus atau seri: Documentation for Pandas.series.mapPemetaan Tidak Lengkap
Jika Anda memiliki pemetaan yang tidak lengkap dan ingin mempertahankan variabel yang ada untuk yang tidak cocok, Anda dapat menambahkan
fillna
:seperti pada jawaban @ jpp di sini: Ganti nilai dalam seri panda melalui kamus secara efisien
Tolak ukur
Menggunakan data berikut dengan panda versi 0.23.1:
dan pengujian dengan
%timeit
, tampaknyamap
sekitar 10x lebih cepat daripadareplace
.Perhatikan bahwa speedup Anda
map
akan berbeda dengan data Anda. Speedup terbesar tampaknya dengan kamus besar dan penggantian lengkap. Lihat jawaban @jpp (ditautkan di atas) untuk tolok ukur dan diskusi yang lebih luas.sumber
df.replace
fungsi, sementara rapi dan berguna untuk dicts kecil, jatuh setelah berjalan selama 20 menit atau lebih.map
juga bekerja pada indeks di mana saya tidak tahu cara untuk melakukan itu denganreplace
Ada sedikit ambiguitas dalam pertanyaan Anda. Setidaknya ada
tigadua interpretasi:di
merujuk pada nilai indeksdi
mengacu padadf['col1']
nilaidi
merujuk ke lokasi indeks (bukan pertanyaan OP, tetapi dilemparkan untuk bersenang-senang.)Di bawah ini adalah solusi untuk setiap kasus.
Kasus 1: Jika kunci
di
dimaksudkan untuk merujuk ke nilai indeks, maka Anda dapat menggunakanupdate
metode ini:Sebagai contoh,
hasil panen
Saya telah memodifikasi nilai dari pos asli Anda sehingga lebih jelas apa
update
yang dilakukan. Perhatikan bagaimana kuncidi
terkait dengan nilai indeks. Urutan nilai indeks - yaitu, lokasi indeks - tidak masalah.Kasus 2: Jika kunci
di
mengacu padadf['col1']
nilai, maka @DanAllan dan @DSM menunjukkan cara mencapai ini denganreplace
:hasil panen
Perhatikan bagaimana dalam hal ini kunci
di
diubah untuk mencocokkan nilai dalamdf['col1']
.Kasus 3: Jika kunci
di
mengacu pada lokasi indeks, maka Anda dapat menggunakannyasejak
hasil panen
Di sini, baris pertama dan ketiga yang diubah, karena kunci dalam
di
adalah0
dan2
, yang dengan pengindeksan 0 berbasis Python mengacu pada lokasi pertama dan ketiga.sumber
replace
sama baiknya, dan mungkin kata yang lebih baik untuk apa yang terjadi di sini.update()
tampaknya agak kumuh dibandingkan denganreplace()
, tetapi setidaknya itu berhasil.Menambahkan ke pertanyaan ini jika Anda memiliki lebih dari satu kolom untuk dipetakan kembali dalam kerangka data data:
Semoga bermanfaat bagi seseorang.
Bersulang
sumber
DataFrame.replace()
, meskipun saya tidak tahu kapan itu ditambahkan.DSM memiliki jawaban yang diterima, tetapi pengkodean tampaknya tidak berfungsi untuk semua orang. Berikut ini adalah yang berfungsi dengan versi panda saat ini (0.23.4 pada 8/2018):
Anda akan melihatnya seperti:
Dokumen untuk panda . DataFrame.replace ada di sini .
sumber
Series.map()
tampaknya lebih fleksibel.Atau lakukan
apply
:Demo:
sumber
di
dict Anda adalah dict daftar? Bagaimana Anda bisa memetakan hanya satu nilai dalam daftar?Diberikan
map
lebih cepat daripada mengganti (solusi @ JohnE) Anda harus berhati -NaN
hati dengan pemetaan Non-Lengkap di mana Anda ingin memetakan nilai tertentu . Metode yang tepat dalam hal ini mengharuskan Andamask
menjadi Seri saat Anda.fillna
, jika tidak Anda membatalkan pemetaanNaN
.sumber
Solusi lengkap yang bagus yang menyimpan peta label kelas Anda:
Dengan cara ini, Anda dapat merujuk label kelas asli dari label_dict kapan saja.
sumber
Sebagai perpanjangan dari apa yang telah diusulkan oleh Nico Coallier (berlaku untuk beberapa kolom) dan U10-Forward (menggunakan gaya metode terapkan), dan meringkasnya menjadi satu-baris yang saya usulkan:
The
.transform()
memproses setiap kolom sebagai seri. Bertentangan dengan.apply()
yang melewati kolom yang dikumpulkan dalam DataFrame.Akibatnya, Anda dapat menerapkan metode Seri
map()
.Akhirnya, dan saya menemukan perilaku ini berkat U10, Anda dapat menggunakan seluruh Seri dalam ekspresi .get (). Kecuali jika saya salah memahami perilakunya dan memproses seri secara berurutan alih-alih dengan sedikit.
The
.get(x,x)
account untuk nilai-nilai Anda tidak menyebutkan dalam kamus pemetaan Anda yang akan dianggap sebagai Nan lain oleh.map()
metodesumber
.transform()
memproses setiap kolom sebagai seri. Bertentangan dengan.apply()
yang melewati kolom yang dikumpulkan dalam DataFrame. Saya baru saja mencoba,apply()
bekerja dengan baik. Tidak perlu menggunakanloc
keduanya, ini tampaknya terlalu rumit.df[["col1", "col2"]].apply(lambda col: col.map(lambda elem: my_dict.get(elem, elem)))
harus bekerja dengan baik. The.get(x,x)
account untuk nilai-nilai Anda tidak menyebutkan dalam kamus pemetaan Anda yang akan dianggap sebagai Nan lain oleh.map()
metode Anda juga bisa menggunakanfillna()
sesudahnya.Pendekatan panda yang lebih asli adalah menerapkan fungsi ganti seperti di bawah ini:
Setelah Anda mendefinisikan fungsi, Anda bisa menerapkannya ke bingkai data Anda.
sumber