Anggap kita menerima data harga jajanan pasar dan diminta menandai produk mana yang tergolong mahal. Aturan penandainya bukan sekadar penjumlahan atau perkalian, melainkan keputusan bercabang yang paling wajar ditulis sebagai fungsi Python biasa. Untuk situasi seperti ini pandas menyediakan method apply(): kita mengoper fungsi kustom, lalu pandas memanggilnya untuk setiap elemen Series atau setiap kolom DataFrame. Chapter ini membahas mekanisme apply() pada Series dan DataFrame, cara mengirim argumen tambahan, serta batasan kapan apply() sebaiknya dipakai.
Cara Kerja apply() #
Method apply() menerima satu fungsi sebagai argumen utama dan memanggil fungsi tersebut secara berurutan pada potongan-potongan data. Pada Series, potongan yang dikirim adalah satu nilai; pada DataFrame, potongannya adalah satu kolom secara default. Setiap nilai balikan dikumpulkan pandas menjadi Series atau DataFrame baru dengan index yang sama dengan objek awalnya. Karena pandas 3.0 selalu menerapkan Copy-on-Write, hasil apply() adalah objek berdiri sendiri dan DataFrame asli tidak pernah berubah.
Dokumentasi resmi merinci kontrak apply() untuk pandas.Series.apply
dan pandas.DataFrame.apply
, sedangkan ringkasannya ada di Essential basic functionality
.
apply() pada Series #
Contoh pertama mengklasifikasikan harga produk menjadi label mahal atau hemat. Fungsi klasifikasi() menerima dua parameter, yaitu satu nilai harga dan satu batas ambang. Kita mengirim fungsi tersebut ke apply() beserta nilai ambangnya melalui parameter args.
import pandas as pd
harga = pd.Series([15000, 32000, 8500, 45000], index=["Kopi", "Teh", "Air", "Coklat"])
def klasifikasi(nilai, batas_mahal):
if nilai >= batas_mahal:
return "mahal"
return "hemat"
kategori = harga.apply(klasifikasi, args=(20000,))
print(harga)
print()
print(kategori)Output yang Dihasilkan:
Kopi 15000
Teh 32000
Air 8500
Coklat 45000
dtype: int64
Kopi hemat
Teh mahal
Air hemat
Coklat mahal
dtype: strMari kita telaah apa yang terjadi pada kode di atas:
- Baris 3: membuat Series
hargadengan index berupa nama produk; dtype-nyaint64karena seluruh isinya bilangan bulat. - Baris 5-9: mendefinisikan fungsi
klasifikasi(); fungsi ini menerima satu nilai dan satu batas, lalu mengembalikan string"mahal"atau"hemat". - Baris 11:
harga.apply(klasifikasi, args=(20000,))memerintahkan pandas memanggilklasifikasi(nilai, 20000)untuk setiap elemen; hasilnya dikumpulkan menjadi Series baru bertipestr. - Baris 13-16: perintah
printmenampilkan Series asli dan Series hasil, sehingga kita dapat membandingkan keduanya.
Perhatikan bahwa apply() tidak mengubah Series harga sama sekali; kategori adalah objek baru. Argumen args=(20000,) ditulis sebagai tuple, karena itu tanda koma setelah angkanya wajib ada. Selain lewat tuple, apply() juga menerima argumen kata kunci: harga.apply(klasifikasi, batas_mahal=20000) menghasilkan keluaran yang persis sama.
apply() pada DataFrame #
Pada DataFrame, apply() secara default memanggil fungsi satu kali per kolom, bukan per sel. Fungsi yang kita kirim menerima sebuah Series kolom dan boleh mengembalikan satu nilai saja. Contoh berikut menghitung amplitudo penjualan, yaitu selisih nilai tertinggi dan terendah pada setiap kolom bulan.
import pandas as pd
penjualan = pd.DataFrame(
{
"Januari": [120, 90, 45],
"Februari": [135, 75, 60],
"Maret": [150, 110, 40],
},
index=["Budi", "Siti", "Dewi"],
)
amplitudo = penjualan.apply(lambda kolom: kolom.max() - kolom.min())
print(penjualan)
print()
print(amplitudo)Output yang Dihasilkan:
Januari Februari Maret
Budi 120 135 150
Siti 90 75 110
Dewi 45 60 40
Januari 75
Februari 75
Maret 110
dtype: int64Mari kita bedah baris demi baris:
- Baris 3-10: membangun DataFrame
penjualandengan tiga kolom bulan dan index berupa nama pegawai. - Baris 12:
apply()tanpa argumenaxismenjalankan lambda satu kali per kolom; parameterkolomberisi SeriesJanuari,Februari, atauMaret. - Baris 12 (lanjutan): ekspresi
kolom.max() - kolom.min()menghitung selisih di dalam Series tersebut, danapply()menampung ketiga hasilnya menjadi Series baru yang index-nya berupa nama kolom. - Baris 14-17: perintah
printmenampilkan tabel asli dan Seriesamplitudountuk perbandingan.
Perilaku default ini setara dengan axis=0, yang artinya fungsi bekerja secara vertikal dari atas ke bawah. Apabila kita ingin fungsi dipanggil satu kali per baris, kita menyetel axis=1; pola itu, termasuk pengembalian beberapa kolom, dibahas tuntas pada Chapter apply() dengan axis di akhir Section ini.
Kapan apply() Sebaiknya Dipakai #
apply() menjalankan fungsi Python melalui loop di balik layar, sehingga lebih lambat dibanding operasi vectorized seperti penjumlahan kolom atau perbandingan boolean. Kebiasaan yang baik adalah mencari alternatif vectorized terlebih dahulu, lalu memilih apply() ketika tidak ada operasi bawaan yang cocok. Tabel berikut merangkum pilihan yang sering kita hadapi.
| Kebutuhan | Pilihan yang lebih cepat |
|---|---|
| Menjumlahkan dua kolom | df["a"] + df["b"] |
| Menandai nilai di atas ambang | df["nilai"] >= 75 |
| Membulatkan seluruh nilai kolom | df["nilai"].round() |
| Logika bercabang khusus per nilai | apply() dengan fungsi kustom |
Baris terakhir tabel adalah wilayah apply(): aturan yang melibatkan percabangan atau pemanggilan fungsi lain yang sulit ditulis sebagai satu ekspresi. Dengan batasan itu, kita memakai apply() untuk pekerjaan yang memang butuh fleksibilitasnya.
Sering kali transformasi yang kita butuhkan bukan fungsi bebas, melainkan penerjemahan nilai ke nilai lain, misalnya kode kota BDG menjadi nama Bandung. Untuk kebutuhan seperti itu pandas menyediakan method khusus bernama map(), berdampingan dengan replace() untuk mengganti nilai tertentu; keduanya menjadi topik Chapter berikutnya.