Cara melakukannya di panda:
Saya memiliki fungsi extract_text_features
pada satu kolom teks, menghasilkan banyak kolom keluaran. Secara khusus, fungsi mengembalikan 6 nilai.
Fungsi ini berfungsi, namun sepertinya tidak ada jenis pengembalian yang tepat (panda DataFrame / array numpy / daftar Python) sehingga output dapat ditugaskan dengan benar df.ix[: ,10:16] = df.textcol.map(extract_text_features)
Jadi saya pikir saya harus kembali ke iterating df.iterrows()
, seperti ini ?
UPDATE: Iterating dengan df.iterrows()
setidaknya 20x lebih lambat, jadi saya menyerah dan membagi fungsi menjadi enam .map(lambda ...)
panggilan berbeda .
UPDATE 2: pertanyaan ini ditanyakan kembali sekitar v0.11.0 . Karenanya banyak pertanyaan dan jawaban tidak terlalu relevan.
df.ix[: ,10:16]
. Saya pikir Anda harus memilikimerge
fitur Anda ke dalam dataset.apply
Jawaban:
Membangun dari jawaban user1827356, Anda dapat melakukan tugas dalam satu pass menggunakan
df.merge
:EDIT: Harap perhatikan konsumsi memori yang besar dan kecepatan rendah: https://ys-l.github.io/posts/2015/08/28/how-not-to-use-pandas-apply/ !
sumber
Saya biasanya melakukan ini menggunakan
zip
:sumber
temp = list(zip(*df['num'].map(powers))); for i, c in enumerate(columns): df[c] = temp[c]
for i, c in enumerate(columns): df[c] = temp[i]
. Berkat ini, saya benar-benar mendapatkan tujuanenumerate
: Dzip(*df['col'].map(function))
mungkin adalah cara untuk pergi.Inilah yang telah saya lakukan di masa lalu
Mengedit untuk kelengkapan
sumber
df[['col1', 'col2']] = df['col3'].apply(lambda x: pd.Series('val1', 'val2'))
Ini adalah cara yang benar dan termudah untuk mencapai hal ini untuk 95% kasus penggunaan:
sumber
pd.Series({k:v})
dan membuat serialisasi tugas kolom seperti dalam jawaban Ewan?Pada 2018, saya menggunakan
apply()
argumenresult_type='expand'
sumber
pd.Series
yang selalu baik tentang masalah kinerjadf.apply
mengembalikan adict
, kolom akan keluar dinamai sesuai dengan tombol.Gunakan saja
result_type="expand"
sumber
Ringkasan: Jika Anda hanya ingin membuat beberapa kolom, gunakan
df[['new_col1','new_col2']] = df[['data1','data2']].apply( function_of_your_choosing(x), axis=1)
Untuk solusi ini, jumlah kolom baru yang Anda buat harus sama dengan kolom angka yang Anda gunakan sebagai input ke fungsi .apply (). Jika Anda ingin melakukan hal lain, lihat jawaban lainnya.
Detail Katakanlah Anda memiliki kerangka data dua kolom. Kolom pertama adalah tinggi seseorang ketika mereka berusia 10 tahun; yang kedua adalah tinggi orang ketika mereka berusia 20 tahun.
Misalkan Anda perlu menghitung rata-rata tinggi dan tinggi masing-masing orang. Itu dua nilai per setiap baris.
Anda dapat melakukan ini melalui fungsi berikut yang segera diterapkan:
Anda mungkin menggunakan fungsi ini seperti:
(Agar lebih jelas: fungsi terapkan ini mengambil nilai dari setiap baris dalam kerangka data yang terdaftar dan mengembalikan daftar.)
Namun, jika Anda melakukan ini:
Anda akan membuat 1 kolom baru yang berisi daftar [rata-rata, jumlah], yang mungkin ingin Anda hindari, karena itu akan membutuhkan Lambda / Terapkan lainnya.
Sebagai gantinya, Anda ingin membagi setiap nilai ke dalam kolomnya sendiri. Untuk melakukan ini, Anda dapat membuat dua kolom sekaligus:
sumber
df["mean"], df["sum"] = df[['height_at_age_10','height_at_age_20']] .apply(mean_and_sum(x),axis=1)
return pd.Series([mean,sum])
Bagi saya ini berhasil:
Masukan df
Fungsi
Buat 2 kolom baru:
Keluaran:
sumber
Saya telah melihat beberapa cara untuk melakukan ini dan metode yang ditampilkan di sini (mengembalikan seri panda) tampaknya tidak paling efisien.
Jika kita mulai dengan kerangka data berukuran besar dari data acak:
Contoh yang ditunjukkan di sini:
Metode alternatif:
Menurut saya itu jauh lebih efisien untuk mengambil serangkaian tupel dan kemudian mengubahnya menjadi DataFrame. Saya akan tertarik mendengar pemikiran orang lain jika ada kesalahan dalam pekerjaan saya.
sumber
Solusi yang diterima akan sangat lambat untuk banyak data. Solusi dengan jumlah upvote terbesar agak sulit dibaca dan juga lambat dengan data numerik. Jika setiap kolom baru dapat dihitung secara independen dari yang lain, saya hanya akan menetapkan masing-masing secara langsung tanpa menggunakan
apply
.Contoh dengan data karakter palsu
Buat 100.000 string dalam DataFrame
Katakanlah kita ingin mengekstraksi beberapa fitur teks seperti yang dilakukan pada pertanyaan awal. Misalnya, mari kita ekstrak karakter pertama, hitung kemunculan huruf 'e' dan gunakan huruf besar frase.
Pengaturan waktu
Anehnya, Anda bisa mendapatkan kinerja yang lebih baik dengan mengulang setiap nilai
Contoh lain dengan data numerik palsu
Buat 1 juta angka acak dan uji
powers
fungsi dari atas.Menetapkan setiap kolom 25x lebih cepat dan sangat mudah dibaca:
Saya membuat respons serupa dengan lebih detail di sini tentang mengapa
apply
biasanya bukan cara untuk pergi.sumber
Telah memposting jawaban yang sama di dua pertanyaan serupa lainnya. Cara saya lebih suka melakukan ini adalah untuk membungkus nilai-nilai pengembalian fungsi dalam suatu seri:
Dan kemudian gunakan terapkan sebagai berikut untuk membuat kolom terpisah:
sumber
Anda dapat mengembalikan seluruh baris alih-alih nilai:
di mana fungsi mengembalikan baris
sumber
extract_text_features
ke setiap kolom df, hanya ke kolom teksdf.textcol
Ini berhasil untuk saya. Kolom Baru akan dibuat dengan data kolom lama yang diproses.
sumber