Misalkan saya punya df
yang memiliki kolom'ID', 'col_1', 'col_2'
. Dan saya mendefinisikan suatu fungsi:
f = lambda x, y : my_function_expression
.
Sekarang saya ingin menerapkan f
ke df
dua kolom 'col_1', 'col_2'
untuk elemen-bijaksana menghitung kolom baru 'col_3'
, agak seperti:
df['col_3'] = df[['col_1','col_2']].apply(f)
# Pandas gives : TypeError: ('<lambda>() takes exactly 2 arguments (1 given)'
Bagaimana melakukan ?
** Tambahkan detail sampel seperti di bawah ini ***
import pandas as pd
df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]})
mylist = ['a','b','c','d','e','f']
def get_sublist(sta,end):
return mylist[sta:end+1]
#df['col_3'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below
ID col_1 col_2 col_3
0 1 0 1 ['a', 'b']
1 2 2 4 ['c', 'd', 'e']
2 3 3 5 ['d', 'e', 'f']
f
yang dilakukanJawaban:
Berikut adalah contoh penggunaan
apply
pada dataframe, yang saya panggilaxis = 1
.Perhatikan perbedaannya adalah bahwa alih-alih mencoba meneruskan dua nilai ke fungsi
f
, tulis ulang fungsi untuk menerima objek Seri panda, lalu indeks Seri untuk mendapatkan nilai yang dibutuhkan.Bergantung pada kasus penggunaan Anda, terkadang bermanfaat untuk membuat
group
objek panda , dan kemudian digunakanapply
pada grup.sumber
sum
berhasil diselesaikan dengan salah satu metode yang disarankan sejauh ini.df
objek yang Anda tetapkan, pendekatan lain (dengan hasil yang setara) adalahdf.apply(lambda x: x[0] + x[1], axis = 1)
.Ada cara bersih dan satu-baris untuk melakukan ini di Panda:
Ini memungkinkan
f
untuk menjadi fungsi yang ditentukan pengguna dengan beberapa nilai input, dan menggunakan nama kolom (aman) daripada indeks numerik (tidak aman) untuk mengakses kolom.Contoh dengan data (berdasarkan pertanyaan asli):
Output dari
print(df)
:Jika nama kolom Anda berisi spasi atau berbagi nama dengan atribut dataframe yang ada, Anda bisa mengindeks dengan tanda kurung:
sumber
axis=1
dan Anda disebut kolomname
itu tidak akan benar-benar mengembalikan data kolom Anda tetapiindex
. Mirip dengan mendapatkanname
digroupby()
. Saya memecahkan masalah ini dengan mengganti nama kolom saya..loc
dalam contoh ini. Mungkin diperlukan jika Anda mengadaptasi ini ke pengaturan masalah lain (misalnya bekerja dengan irisan).Solusi sederhana adalah:
sumber
Pertanyaan yang menarik! jawaban saya seperti di bawah ini:
Keluaran:
Saya mengubah nama kolom menjadi ID, J1, J2, J3 untuk memastikan ID <J1 <J2 <J3, sehingga kolom ditampilkan dalam urutan yang benar.
Satu lagi versi singkat:
sumber
Metode yang Anda cari adalah Series.combine. Namun, tampaknya beberapa perawatan harus dilakukan di sekitar tipe data. Dalam contoh Anda, Anda akan (seperti yang saya lakukan ketika menguji jawaban) secara naif menelepon
Namun, ini melempar kesalahan:
Tebakan terbaik saya adalah sepertinya hasilnya hasilnya sama dengan seri yang memanggil metode (df.col_1 di sini). Namun, berikut ini berfungsi:
sumber
Cara Anda menulis f membutuhkan dua input. Jika Anda melihat pesan kesalahan itu mengatakan Anda tidak memberikan dua input ke f, hanya satu. Pesan kesalahan sudah benar.
Ketidakcocokan karena df [['col1', 'col2']] mengembalikan satu kerangka data tunggal dengan dua kolom, bukan dua kolom terpisah.
Anda perlu mengubah f sehingga dibutuhkan satu input, simpan frame data di atas sebagai input, lalu pisahkan menjadi x, y di dalam fungsi body. Kemudian lakukan apa pun yang Anda butuhkan dan kembalikan satu nilai.
Anda memerlukan tanda tangan fungsi ini karena sintaksnya adalah .apply (f) Jadi f perlu mengambil satu hal = dataframe dan bukan dua hal yang diharapkan oleh f saat ini.
Karena Anda belum memberikan isi f saya tidak bisa membantu dalam detail lagi - tetapi ini harus memberikan jalan keluar tanpa secara mendasar mengubah kode Anda atau menggunakan beberapa metode lain daripada menerapkan
sumber
Saya akan memberikan suara untuk np.vectorize. Ini memungkinkan Anda untuk hanya mengambil lebih dari x jumlah kolom dan tidak berurusan dengan kerangka data dalam fungsi, jadi bagus untuk fungsi yang tidak Anda kontrol atau lakukan sesuatu seperti mengirim 2 kolom dan konstanta ke fungsi (yaitu col_1, col_2, 'foo').
sumber
Mengembalikan daftar dari
apply
adalah operasi yang berbahaya karena objek yang dihasilkan tidak dijamin sebagai Seri atau DataFrame. Dan pengecualian mungkin dimunculkan dalam kasus-kasus tertentu. Mari kita telusuri contoh sederhana:Ada tiga kemungkinan hasil dengan mengembalikan daftar dari
apply
1) Jika panjang daftar yang dikembalikan tidak sama dengan jumlah kolom, maka serangkaian daftar dikembalikan.
2) Ketika panjang daftar yang dikembalikan sama dengan jumlah kolom maka DataFrame dikembalikan dan setiap kolom mendapatkan nilai yang sesuai dalam daftar.
3) Jika panjang daftar yang dikembalikan sama dengan jumlah kolom untuk baris pertama tetapi memiliki setidaknya satu baris di mana daftar memiliki jumlah elemen yang berbeda dari jumlah kolom, ValueError dinaikkan.
Menjawab masalah tanpa mendaftar
Menggunakan
apply
dengan sumbu = 1 sangat lambat. Dimungkinkan untuk mendapatkan kinerja yang jauh lebih baik (terutama pada dataset yang lebih besar) dengan metode iteratif dasar.Buat kerangka data yang lebih besar
Pengaturan waktu
@ Thomas menjawab
sumber
Saya yakin ini tidak secepat solusi menggunakan operasi Pandas atau Numpy, tetapi jika Anda tidak ingin menulis ulang fungsi Anda, Anda dapat menggunakan peta. Menggunakan data contoh asli -
Kami bisa memberikan argumen sebanyak yang kami inginkan ke dalam fungsi dengan cara ini. Output adalah apa yang kami inginkan
sumber
apply
denganaxis=1
Contoh saya untuk pertanyaan Anda:
sumber
Jika Anda memiliki kumpulan data yang sangat besar, maka Anda dapat menggunakan cara yang lebih mudah (lebih cepat) untuk melakukan ini menggunakan swifter:
sumber
Saya kira Anda tidak ingin mengubah
get_sublist
fungsi, dan hanya ingin menggunakanapply
metode DataFrame untuk melakukan pekerjaan itu. Untuk mendapatkan hasil yang Anda inginkan, saya telah menulis dua fungsi bantuan:get_sublist_list
danunlist
. Seperti yang disarankan oleh nama fungsi, pertama-tama dapatkan daftar sublist, ekstrak kedua sublist itu dari daftar itu. Akhirnya, Kita perlu memanggilapply
fungsi untuk menerapkan kedua fungsi tersebut kedf[['col_1','col_2']]
DataFrame selanjutnya.Jika Anda tidak menggunakan
[]
untuk melampirkanget_sublist
fungsi, makaget_sublist_list
fungsi akan mengembalikan daftar polos, itu akan naikValueError: could not broadcast input array from shape (3) into shape (2)
, seperti @Ted Petrou telah sebutkan.sumber