Lewati ke konten utama

Cara Menggunakan PySpark UDF dan Pandas UDF Secara Efektif

Pelajari cara membuat, mengoptimalkan, dan menggunakan PySpark UDF, termasuk Pandas UDF, untuk menangani transformasi data kustom secara efisien dan meningkatkan performa Spark.
Diperbarui 28 Sep 2026  · 9 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

User-Defined Functions (UDF) di PySpark menawarkan cara yang kuat bagi pengembang Python untuk menangani tugas-tugas unik yang tidak dapat diatasi oleh fungsi bawaan Spark. Jika Anda adalah data engineer, analis, atau ilmuwan data yang mahir dalam Python, memahami konsep UDF dapat memungkinkan Anda menangani tantangan data dunia nyata yang kompleks secara efektif. 

Tutorial ini memandu Anda melalui konsep UDF PySpark, implementasi praktis, serta praktik terbaik dalam optimasi, pengujian, debugging, dan pola penggunaan lanjutan. Pada akhirnya, Anda akan mampu menulis, mengoptimalkan, dan menerapkan UDF yang efisien dalam skala besar dengan percaya diri.

Jika Anda baru mengenal PySpark, saya sarankan terlebih dahulu melihat tutorial Memulai dengan PySpark karena yang kita bahas di sini adalah konsep Spark tingkat lanjut.

Apa itu PySpark UDF?

PySpark UDF adalah fungsi Python kustom yang diintegrasikan ke dalam kerangka kerja terdistribusi Spark untuk beroperasi pada data yang disimpan dalam Spark DataFrame. Tidak seperti fungsi bawaan Spark, UDF memungkinkan pengembang menerapkan logika kustom yang kompleks pada tingkat baris atau kolom. 

Lembar Contekan PySpark kami mencakup semua yang perlu Anda ketahui tentang Spark DataFrame, sehingga memudahkan Anda memahami Spark UDF. 

Kapan sebaiknya Anda menggunakan PySpark UDF?

Gunakan UDF ketika:

  • Anda memerlukan logika yang tidak dapat diekspresikan menggunakan fungsi bawaan Spark.
  • Transformasi Anda melibatkan operasi kompleks yang khas Python (misalnya, manipulasi regex, logika NLP kustom).
  • Anda bersedia menukar performa demi fleksibilitas, terutama saat prototyping atau untuk dataset kecil hingga menengah.

Hindari UDF ketika:

  • Fungsionalitas yang setara ada di pyspark.sql.functions; fungsi native Spark lebih cepat, dioptimalkan, dan dapat diteruskan ke mesin eksekusi.
  • Anda bekerja dengan dataset besar di mana performa sangat penting. UDF memperkenalkan overhead serialisasi dan memutus kemampuan Spark untuk mengoptimalkan rencana eksekusi.
  • Anda dapat mengekspresikan logika menggunakan ekspresi SQL, fungsi bawaan Spark SQL, atau Pandas UDF (untuk operasi vektorisasi).

Aplikasi strategis dalam rekayasa data

Berikut adalah kasus penggunaan utama untuk PySpark UDF:

  • Transformasi data kompleks, seperti parsing teks tingkat lanjut, ekstraksi data, atau manipulasi string.
  • Integrasi dengan pustaka pihak ketiga berbasis Python, termasuk kerangka kerja machine learning populer seperti TensorFlow dan XGBoost.
  • Menjembatani sistem legacy dan mendukung evolusi skema yang mulus saat struktur data berubah.

UDF menyederhanakan tugas rekayasa data dunia nyata yang berantakan, memberdayakan tim untuk menangani berbagai kebutuhan secara fleksibel dan efektif. 

Sekarang mari kita lihat bagaimana Anda dapat mengimplementasikan PySpark UDF. 

Mengimplementasikan PySpark UDF

Bagian ini menguraikan cara mendefinisikan dan mengimplementasikan PySpark UDF secara praktis.

Metode deklarasi UDF standar

Ada tiga pendekatan umum untuk mendeklarasikan UDF di PySpark:

1. UDF berbasis lambda: Cepat didefinisikan langsung di dalam kueri DataFrame; terbaik untuk operasi sederhana.

UDF berbasis lambda (UDF Python dasar) paling cocok untuk transformasi yang cepat dan sederhana. Hindari untuk pekerjaan skala besar di mana performa penting.

Berikut contohnya: 

from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

uppercase = udf(lambda x: x.upper() if x else None, StringType())
df = spark.createDataFrame([("Ada",), (None,)], ["name"])
df.withColumn("upper_name", uppercase("name")).show()

2. Fungsi Python dengan dekorator: Dianotasi secara eksplisit menggunakan @pyspark.sql.functions.udf, mendukung reusabilitas dan keterbacaan.

Contohnya:

from pyspark.sql import functions as F
from pyspark.sql.types import IntegerType

@F.udf(returnType=IntegerType())
def str_length(s):
    return len(s) if s else 0

df.withColumn("name_length", str_length("name")).show()

3. UDF terdaftar di SQL: Didaftarkan langsung dalam konteks Spark SQL, memungkinkan penggunaannya di dalam kueri SQL.

from pyspark.sql.types import StringType

def reverse_string(s):
    return s[::-1] if s else ""

spark.udf.register("reverse_udf", reverse_string, StringType())

df.createOrReplaceTempView("people")
spark.sql("""SELECT name, reverse_udf(name) AS reversed FROM people""").show()

Setiap metode memiliki trade-off: UDF lambda ringkas namun terbatas, sementara anotasi fungsi mendukung keterbacaan, kemudahan pemeliharaan, dan praktik terbaik.

Pandas UDF memungkinkan operasi vektorisasi pada batch Arrow. Mereka sering lebih cepat daripada UDF biasa dan lebih baik terintegrasi dengan mesin eksekusi Spark.

Pandas UDF Skalar (per elemen, seperti map)

Paling cocok untuk transformasi cepat per baris pada dataset besar. Misalnya: 

from pyspark.sql.functions import pandas_udf
from pyspark.sql.types import IntegerType
import pandas as pd

@pandas_udf(IntegerType())
def pandas_strlen(s: pd.Series) -> pd.Series:
    return s.str.len()

df.withColumn("name_len", pandas_strlen("name")).show()

Pandas UDF Grouped Map

Paling cocok untuk logika kustom per grup, mirip dengan groupby().apply() di Pandas.  

from pyspark.sql import functions as F
from pyspark.sql.types import StructType, StructField, StringType, DoubleType
import pandas as pd

schema = StructType([
    StructField("group", StringType()),
    StructField("avg_val", DoubleType())
])

@pandas_udf(schema, F.PandasUDFType.GROUPED_MAP)
def group_avg(pdf: pd.DataFrame) -> pd.DataFrame:
    return pd.DataFrame({
        "group": [pdf["group"].iloc[0]],
        "avg_val": [pdf["value"].mean()]
    })

df.groupBy("group").apply(group_avg).show()

Pandas Aggregate UDF

Yang ini melakukan agregasi per grup, lebih cepat daripada grouped map. Misalnya: 

from pyspark.sql.functions import pandas_udf
from pyspark.sql.types import DoubleType
import pandas as pd

@pandas_udf(DoubleType(), functionType="grouped_agg")
def mean_udf(v: pd.Series) -> float:
    return v.mean()

df.groupBy("category").agg(mean_udf("value").alias("mean_value")).show()

Pandas Iterator UDF

Pandas Iterator UDF paling cocok untuk dataset besar yang memerlukan pemrosesan berdaya memori rendah (per batch). Contohnya: 

from pyspark.sql.functions import pandas_udf
from pyspark.sql.types import IntegerType
from typing import Iterator
import pandas as pd

@pandas_udf(IntegerType(), functionType="iterator")
def batch_sum(it: Iterator[pd.Series]) -> Iterator[pd.Series]:
    for batch in it:
        yield batch + 1

df.withColumn("incremented", batch_sum("id")).show()

Penanganan tipe dan keamanan null

Tipe dan nilai null sering menjadi tantangan bagi PySpark UDF. PySpark menerapkan pemeriksaan tipe yang ketat, yang sering menyebabkan konversi tipe implisit atau masalah saat runtime. Selain itu, Spark meneruskan nilai null langsung ke UDF, yang dapat menyebabkan crash jika tidak ditangani secara eksplisit.

Pastikan UDF yang tangguh dengan strategi berikut:

  • Tentukan tipe keluaran secara eksplisit.
  • Sertakan pemeriksaan null (misalnya, pernyataan kondisional) di dalam fungsi Python Anda.
  • Adopsi praktik pengkodean defensif; pemeriksaan null sederhana mencegah pengecualian runtime yang menjengkelkan.

Mengoptimalkan Performa UDF

Performa sering menjadi titik lemah utama untuk UDF standar karena model eksekusinya per baris. Memanfaatkan UDF vektorisasi dan alat optimasi Spark akan sangat meningkatkan waktu eksekusi.

UDF tervektorisasi dengan integrasi Pandas

Pandas UDF memperkenalkan pendekatan vektorisasi pada UDF di PySpark dengan meneruskan batch data sebagai Pandas Series ke fungsi Python. Desain ini secara signifikan meningkatkan performa dengan mengurangi overhead serialisasi dibandingkan UDF berbasis baris standar.

Didukung oleh Apache Arrow untuk transfer data zero-copy antara JVM dan proses Python, Pandas UDF memungkinkan eksekusi operasi yang efisien dalam skala besar. Mereka sangat efektif untuk komputasi intensif dan manipulasi string kompleks pada jutaan rekaman. 

Kami membahas lebih detail tentang manipulasi data dengan PySpark dalam kursus Cleaning Data with PySpark kami. 

Selain itu, Pandas UDF memungkinkan integrasi yang mulus dengan ekosistem data science Python yang lebih luas, memanfaatkan alat dan alur kerja yang familier.

Jenis UDF

Gaya Eksekusi

Kecepatan

Optimasi Spark

Terbaik Untuk

Catatan

UDF Standar

Per baris (Python)

Lambat

Tidak dioptimalkan

Logika sederhana, dataset kecil

Mudah ditulis, tetapi mahal

Pandas UDF Skalar

Tervektorisasi (per kolom)

Cepat

Didukung Arrow

Operasi numerik, transformasi string

Gunakan dibandingkan UDF standar bila memungkinkan

Pandas UDF Grouped Map

Per grup (Pandas DataFrame)

Sedang–Cepat

Didukung Arrow

Transformasi per grup

Skema keluaran harus didefinisikan manual

Pandas UDF Agregat

Per grup (masukan Series → keluaran skalar)

Cepat

Dioptimalkan

Agregasi seperti mean, sum

Lebih sederhana daripada grouped map

Pandas Iterator UDF

Iterator batch (streaming)

Cepat

Dioptimalkan

Memproses batch besar dengan aman

Jejak memori lebih rendah

Teknik optimasi Arrow

Format memori kolumnar Apache Arrow memungkinkan transfer data yang efisien dan zero-copy antara Spark JVM dan proses Python. Dengan mengaktifkan Arrow (spark.sql.execution.arrow.pyspark.enabled=true) dalam konfigurasi Spark Anda, data berpindah cepat antara lingkungan JVM dan Python, sehingga mempercepat eksekusi UDF secara signifikan.

Optimasi rencana eksekusi

Mengoptimalkan pekerjaan PySpark melibatkan pemahaman cara memengaruhi optimizer Catalyst milik Spark. Strategi lanjutan mencakup teknik seperti predicate pushdown, pemangkasan kolom, dan penggunaan petunjuk broadcast join untuk meningkatkan perencanaan kueri dan efisiensi eksekusi.

Untuk memaksimalkan performa, penting untuk meminimalkan cakupan eksekusi UDF dan lebih memilih fungsi bawaan Spark SQL kapan pun memungkinkan. Penggunaan caching yang strategis dan perancangan rencana yang cermat dapat semakin meningkatkan kecepatan eksekusi pekerjaan dan pemanfaatan sumber daya.

Optimasi performa adalah salah satu pertanyaan utama yang mungkin Anda temui dalam wawancara PySpark. Temukan cara menjawab ini dan pertanyaan Spark lainnya dalam 36 Pertanyaan dan Jawaban Wawancara PySpark Teratas untuk 2025 di blog kami. 

Pola Lanjutan dan Anti-Pattern

Memahami pola penggunaan yang tepat dan tidak tepat membantu memastikan penerapan UDF yang stabil dan efisien.

Implementasi UDF stateful

UDF stateful dan non-deterministik menghadirkan tantangan unik di PySpark. Fungsi-fungsi ini menghasilkan hasil yang bergantung pada state eksternal atau kondisi yang berubah, seperti variabel lingkungan, waktu sistem, atau konteks sesi.

Meskipun UDF non-deterministik kadang diperlukan—misalnya untuk menghasilkan stempel waktu, melacak sesi pengguna, atau memasukkan unsur acak—UDF dapat mempersulit debugging, reprodusibilitas, dan optimasi.

Mengimplementasikan UDF stateful memerlukan pola desain yang cermat: mendokumentasikan perilaku dengan jelas, mengisolasi efek samping, dan menambahkan logging yang menyeluruh untuk membantu pemecahan masalah serta memastikan konsistensi di setiap run pekerjaan.

Jika digunakan dengan bijak, UDF ini dapat membuka kemampuan yang kuat, namun mempertahankan pipeline data yang andal memerlukan pengelolaan yang disiplin. Kursus Big Data Fundamentals with PySpark kami membahas lebih detail tentang cara menangani big data di PySpark. 

Anti-pattern umum

Anti-pattern umum dalam penggunaan UDF dapat sangat menurunkan performa PySpark:

  • Pemrosesan per baris alih-alih per batch: Menerapkan UDF pada setiap baris alih-alih menggunakan pendekatan vektorisasi seperti Pandas UDF menyebabkan perlambatan eksekusi yang besar.
  • Operasi DataFrame bersarang di dalam UDF: Menyematkan kueri DataFrame di dalam UDF menyebabkan komputasi berlebihan dan menghambat kemampuan Spark untuk mengoptimalkan rencana eksekusi.
  • Pendaftaran UDF inline berulang: Mendefinisikan dan mendaftarkan UDF berkali-kali di dalam kueri menambah overhead yang tidak perlu; lebih baik mendeklarasikan UDF sekali dan menggunakannya kembali di berbagai pekerjaan.
  • Terlalu sering menggunakan logika Python kustom untuk operasi sederhana: Tugas seperti penyaringan dasar, aritmetika, atau transformasi yang lugas sebaiknya menggunakan fungsi bawaan Spark yang sangat dioptimalkan ketimbang UDF kustom.

Menghindari jebakan ini memastikan performa lebih baik, memudahkan optimasi oleh Catalyst, dan kode PySpark yang lebih mudah dipelihara.

Debugging dan Pengujian PySpark UDF

Pengujian dan debugging UDF memastikan keandalan dan ketangguhan dalam skenario produksi.

Pola penanganan pengecualian

Menerapkan penangkapan error terstruktur di dalam UDF sangat penting untuk membangun pipeline PySpark yang tangguh dan mudah dipelihara. Gunakan blok try-except di dalam UDF untuk menangani kejutan runtime dengan baik, seperti nilai null, ketidakcocokan tipe, atau error pembagian dengan nol.

Penanganan pengecualian yang kuat menstabilkan pipeline terhadap data tak terduga dan menyederhanakan debugging dengan menampilkan pesan error yang jelas dan dapat ditindaklanjuti. Pengecualian yang ditangkap dan dicatat dengan benar membuat perilaku UDF lebih transparan, mempercepat penyelesaian masalah dan meningkatkan keandalan pipeline secara keseluruhan.

Kerangka kerja unit testing

Gunakan kelas dasar pengujian bawaan PySpark, pyspark.testing.utils.ReusedPySparkTestCase, bersama kerangka kerja seperti pytest, untuk menulis unit test yang andal bagi UDF Anda. Menyusun pengujian yang jelas dan fokus memastikan kebenaran, stabilitas, dan kemudahan pemeliharaan logika UDF Anda dari waktu ke waktu.

Praktik terbaik untuk menguji UDF mencakup mencakup kasus umum dan edge case, memvalidasi keluaran terhadap hasil yang diketahui, serta mengisolasi perilaku UDF dari dependensi eksternal. Pengujian yang dirancang dengan baik tidak hanya melindungi dari regresi tetapi juga menyederhanakan pengembangan dan refaktorisasi di masa mendatang.

Evolusi dan Arah Masa Depan

Ekosistem PySpark terus berkembang pesat, menghadirkan kemampuan baru yang semakin meningkatkan UDF.

Integrasi Unity Catalog

Perkembangan terbaru telah mengintegrasikan pendaftaran UDF ke dalam Unity Catalog, menyederhanakan cara UDF dikelola, ditemukan, dan diatur dalam skala besar. Unity Catalog memungkinkan kontrol terpusat atas manajemen siklus hidup UDF, termasuk pendaftaran, versioning, dan kontrol akses, yang semuanya penting untuk lingkungan enterprise.

Integrasi ini meningkatkan tata kelola, menegakkan kebijakan keamanan yang konsisten, dan meningkatkan keterjangkauan lintas tim, sehingga UDF lebih mudah digunakan kembali, diaudit, dan dikelola dalam ekosistem data yang besar dan kompleks.

UDF dengan akselerasi GPU

Kerangka kerja seperti RAPIDS Accelerator memungkinkan offloading GPU untuk tugas UDF yang intensif komputasi di PySpark, menawarkan peningkatan performa yang transformasional. Dengan memindahkan operasi berat, seperti analisis numerik, inferensi deep learning, dan pemodelan data skala besar, ke GPU, RAPIDS dapat mengurangi waktu eksekusi dari jam menjadi menit pada beban kerja yang sesuai.

Akselerasi GPU sangat bermanfaat untuk skenario yang melibatkan dataset masif, komputasi tervektorisasi yang kompleks, dan pipeline machine learning, sehingga secara dramatis memperluas performa dan skalabilitas PySpark untuk tugas rekayasa data modern. Kursus Machine Learning with PySpark kami membahas konsep-konsep ini lebih dalam. 

Kesimpulan

PySpark UDF adalah alat yang kuat untuk memperluas kapabilitas Spark, memungkinkan tim menangani tugas pemrosesan data yang kompleks dan kustom yang melampaui fungsi bawaan. Jika diterapkan dengan benar, UDF membuka fleksibilitas dan inovasi dalam pipeline data skala besar. 

Namun, mengoptimalkan performa UDF memerlukan perhatian cermat, menghindari jebakan umum seperti operasi per baris, mengelola pengecualian dengan baik, dan memanfaatkan teknik seperti vektorisasi Pandas UDF dengan integrasi Arrow.

Kemajuan yang muncul, seperti akselerasi GPU melalui kerangka kerja seperti RAPIDS, semakin memperluas kemungkinan dengan alur kerja berbasis UDF. Baik Anda mentransformasi data dunia nyata yang berantakan maupun menyematkan analitik lanjutan ke dalam sistem produksi, menguasai praktik terbaik UDF sangat penting untuk membangun pipeline data yang cepat, efisien, dan andal. 

Pelajari seluk-beluk yang menyita 70–80% waktu ilmuwan data—data wrangling dan feature engineering—melalui kursus Feature Engineering with PySpark kami.

FAQ PySpark UDF

Kapan saya harus menggunakan PySpark UDF alih-alih fungsi bawaan?

Anda sebaiknya menggunakan PySpark UDF hanya ketika transformasi Anda tidak dapat dicapai menggunakan fungsi bawaan Spark. Fungsi bawaan telah dioptimalkan dan berjalan lebih cepat daripada UDF karena beroperasi secara native di JVM tanpa overhead serialisasi.

Mengapa Pandas UDF lebih cepat daripada UDF Python biasa di PySpark?

Pandas UDF (UDF tervektorisasi) lebih cepat karena menggunakan Apache Arrow untuk serialisasi data yang efisien dan memproses data dalam batch alih-alih per baris, yang mengurangi overhead perpindahan data antara JVM dan interpreter Python.

Apakah saya selalu perlu menentukan tipe keluaran untuk UDF di PySpark?

Ya, PySpark memerlukan tipe data keluaran yang eksplisit saat mendefinisikan UDF. Persyaratan ini memastikan serialisasi yang tepat antara Java dan Python serta mencegah error saat runtime.

Bagaimana cara mengaktifkan Apache Arrow dalam aplikasi PySpark saya?

Anda dapat mengaktifkan Apache Arrow dengan menetapkan konfigurasi berikut sebelum menjalankan UDF apa pun:

spark.conf.set("spark.sql.execution.arrow.pyspark.enabled", "true")

Apa cara terbaik menangani nilai null dalam PySpark UDF?

Selalu sertakan pemeriksaan kondisi untuk nilai None (null) di UDF Anda guna menghindari pengecualian. Misalnya: if product_name is None: return None.


Derrick Mwiti's photo
Author
Derrick Mwiti
Topik
PySpark
Python
Rekayasa Data

Kursus Teratas di DataCamp

Kursus

Pengantar PySpark

4 jam
34.9K
Kuasai PySpark untuk kelola big data dengan mudah—pelajari proses, mengambil, dan optimalkan dataset besar untuk analitik ampuh!
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

Lihat SelengkapnyaLihat Selengkapnya