Sebuah laporan penjualan biasanya melewati banyak tahapan: menyaring baris yang tidak relevan, menambahkan kolom perhitungan, lalu merapikan hasil. Apabila setiap tahap ditulis terpisah, notebook kita penuh variabel perantara; apabila dirangkai method demi method, tidak ada tempat alami untuk menyisipkan fungsi buatan sendiri. Method pipe() mengatasi kedua masalah itu dengan memasukkan fungsi bebas ke dalam rantai DataFrame. Chapter ini membahas mekanisme pipe(), cara mengirim argumen ke fungsinya, dan cara menyusun pipeline yang nyaman dibaca.
Mekanisme pipe() #
Aturan pipe() sederhana: df.pipe(fungsi, argumen_lain) persis sama dengan fungsi(df, argumen_lain). pandas mengambil DataFrame sebagai argumen pertama fungsi, lalu memakai nilai balik fungsi tersebut sebagai objek untuk langkah berikutnya dalam rantai. Karena hasilnya kembali berupa DataFrame, kita bebas merangkai method apa pun setelahnya. Data asli tidak berubah selama fungsi kita tidak memodifikasinya, sejalan dengan perilaku Copy-on-Write di pandas 3.0.
import pandas as pd
def saring_harga(df, kolom, batas):
return df[df[kolom] <= batas]
def tambah_total(df):
return df.assign(total=df["harga"] * df["jumlah"])
pesanan = pd.DataFrame(
{
"produk": ["Kopi Gayo", "Teh Melati", "Gula Aren", "Kopi Toraja"],
"harga": [85000, 32000, 24000, 90000],
"jumlah": [12, 30, 25, 5],
}
)
hasil = pesanan.pipe(saring_harga, kolom="harga", batas=88000).pipe(tambah_total)
print(pesanan)
print()
print(hasil)Output yang Dihasilkan:
produk harga jumlah
0 Kopi Gayo 85000 12
1 Teh Melati 32000 30
2 Gula Aren 24000 25
3 Kopi Toraja 90000 5
produk harga jumlah total
0 Kopi Gayo 85000 12 1020000
1 Teh Melati 32000 30 960000
2 Gula Aren 24000 25 600000Mari kita telaah apa yang terjadi pada kode di atas:
- Baris 4-5: mendefinisikan
saring_harga(); fungsi menerima DataFrame dan dua argumen saringan, lalu mengembalikan DataFrame hasil seleksi baris. - Baris 8-9: mendefinisikan
tambah_total(); fungsi menerima DataFrame dan mengembalikan versi baru dengan kolomtotal, memakaiassign()dari Chapter sebelumnya. - Baris 12-18: membangun DataFrame
pesananberisi empat produk. - Baris 20:
pipe()pertama memanggilsaring_harga(pesanan, kolom="harga", batas=88000);pipe()kedua memanggiltambah_total()dengan hasil saringan tadi sebagai argumennya. - Baris 22-24: perintah
printmenampilkanpesananasli yang tetap empat baris danhasilyang tinggal tiga baris ditambah kolomtotal.
Perhatikan urutan eksekusinya: saringan dulu, penambahan kolom kemudian. Baris Kopi Toraja dengan harga 90000 hilang pada tahap pertama, sehingga tambah_total() hanya menghitung tiga baris tersisa. Apabila urutan kedua pipe() dibalik, kolom total tetap dihitung untuk empat baris dan barisnya baru disaring setelah itu — jumlah akhirnya sama, namun isi kolom total untuk data mentah menjadi berbeda.
Mengirim Argumen ke Fungsi #
Semua argumen tambahan setelah nama fungsi diteruskan pipe() apa adanya. Argumen posisi disalin sesuai urutan penulisannya, sedangkan argumen kata kunci seperti kolom= dan batas= diserahkan beserta namanya. Dengan sifat itu, satu fungsi dapat dipakai ulang untuk beberapa tahap dengan saringan berbeda: pipe(saring_harga, kolom="jumlah", batas=20) menyaring berdasarkan kolom lain tanpa perlu membuat fungsi baru. Pola ini menjaga jumlah fungsi kecil, karena perbedaan kebutuhan ditangani oleh argumen, bukan oleh salinan fungsi.
Pipeline yang Terbaca dari Atas ke Bawah #
Keuntungan terbesar pipe() ada pada bentuk akhir kode. Tanpa pipe(), komposisi fungsi menjadi bersarang seperti tambah_total(saring_harga(pesanan, ...)), dan kedalaman bersarang itu bertambah setiap kali tahapan baru muncul. Dengan pipe(), setiap tahap menempati satu potongan rantai dalam urutan eksekusi, sehingga pembaca menelusuri alur dari atas ke bawah seperti membaca resep.
| Penulisan | Wujudnya |
|---|---|
Bersarang: tambah_total(saring_harga(pesanan, ...)) | Semakin sulit dibaca saat tahapan bertambah |
Variabel perantara: df1 = saring_harga(...), df2 = tambah_total(df1) | Banyak nama sementara yang mudah tercampur |
Rantai: pesanan.pipe(saring_harga, ...).pipe(tambah_total) | Satu alur dengan urutan eksekusi yang jelas |
Dokumentasi pandas.DataFrame.pipe
merinci parameter pipe(), termasuk dukungan argumen kata kunci yang kita pakai di atas. Halaman Essential basic functionality
menempatkan pipe() sebagai bagian dari pola function application, berdampingan dengan apply() dan map() yang sudah kita pelajari sebelumnya.
Rantai pipe() yang panjang sering kali berakhir pada perhitungan statistik per kelompok, misalnya rata-rata skor setiap kelompok belajar. Di sanalah dua method saudara, aggregate() dan transform(), bermain peran dengan cara yang sangat berbeda; kita bandingkan keduanya pada Chapter berikutnya.