Tutorial Polars: DataFrame Library Ultra-Cepat untuk Data Science

# Polars - Tutorial Lengkap Library DataFrame Ultra-Cepat ## Daftar Isi 1. [Pendahuluan](#pendahuluan) 2. [Prasyarat](#prasyarat) 3. [Dasar-Dasar Polars](#dasar-dasar-polars) 4. [Evaluasi Lazy vs Ea...

By Ruby Abdullah · · tutorial
PolarsDataFrameData SciencePythonPandas AlternativePerformance

Polars - Tutorial Lengkap Library DataFrame Ultra-Cepat

Daftar Isi

  • Pendahuluan
  • Prasyarat
  • Dasar-Dasar Polars
  • Evaluasi Lazy vs Eager
  • Ekspresi dan Transformasi
  • Join dan Penggabungan DataFrame
  • Group By dan Agregasi
  • Fungsi Window
  • Benchmark Polars vs Pandas
  • Integrasi Pipeline ML
  • Menangani Dataset Besar dengan Streaming
  • Praktik Terbaik
  • Kesimpulan

  • Pendahuluan

    Polars adalah library DataFrame yang sangat cepat, ditulis dalam Rust dengan binding Python. Library ini memanfaatkan format memori kolumnar Apache Arrow dan mesin query multi-thread untuk memberikan performa yang seringkali 10-100x lebih cepat dari Pandas. Polars mendukung evaluasi eager dan lazy, menjadikannya ideal untuk analisis data eksploratif maupun pipeline data produksi.

    Keunggulan utama Polars dibandingkan Pandas:

    • Ditulis dalam Rust dengan interoperabilitas zero-copy melalui Apache Arrow
    • Eksekusi multi-thread secara default
    • Evaluasi lazy dengan optimasi query
    • API yang konsisten tanpa kebingungan berbasis indeks
    • Dukungan streaming untuk pemrosesan out-of-core

    Prasyarat

    • Python 3.8 atau lebih tinggi
    • Pemahaman dasar tentang DataFrame dan data tabular

    pip install polars
    

    pip install polars[all] # Termasuk dependensi opsional (Excel, konektor database, dll.)

    pip install pandas # Untuk benchmark perbandingan

    pip install scikit-learn # Untuk contoh pipeline ML

    Dasar-Dasar Polars

    Membuat DataFrame

    import polars as pl
    
    

    Dari dictionary

    df = pl.DataFrame({

    "nama": ["Alice", "Bob", "Charlie", "Diana", "Eve"],

    "umur": [30, 25, 35, 28, 32],

    "departemen": ["Teknik", "Pemasaran", "Teknik", "Penjualan", "Pemasaran"],

    "gaji": [95000, 65000, 105000, 72000, 78000],

    "tanggalmasuk": ["2020-01-15", "2021-06-01", "2019-03-20", "2022-01-10", "2020-09-05"]

    })

    Konversi kolom tanggal

    df = df.withcolumns(pl.col("tanggalmasuk").str.todate())

    print(df)

    print(f"Bentuk: {df.shape}")

    print(f"Skema: {df.schema}")

    print(f"Tipe data: {df.dtypes}")

    Membaca Data

    # CSV
    

    df = pl.readcsv("data.csv")

    Parquet (sangat direkomendasikan untuk performa)

    df = pl.readparquet("data.parquet")

    JSON

    df = pl.readjson("data.json")

    Dari Pandas

    import pandas as pd

    pandasdf = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})

    polarsdf = pl.frompandas(pandasdf)

    Kembali ke Pandas jika diperlukan

    pandaskembali = polarsdf.topandas()

    Operasi Dasar

    # Pilih kolom
    

    df.select("nama", "gaji")

    df.select(pl.col("nama"), pl.col("gaji"))

    Filter baris

    df.filter(pl.col("gaji") > 80000)

    df.filter((pl.col("departemen") == "Teknik") & (pl.col("umur") > 30))

    Urutkan

    df.sort("gaji", descending=True)

    df.sort(["departemen", "gaji"], descending=[False, True])

    Tambah/modifikasi kolom

    df.withcolumns(

    (pl.col("gaji") 1.1).alias("gajisetelahkenaikan"),

    pl.col("nama").str.touppercase().alias("namakapital"),

    pl.lit("Aktif").alias("status")

    )

    Hapus kolom

    df.drop("tanggalmasuk")

    Ubah nama kolom

    df.rename({"nama": "namakaryawan", "gaji": "gajitahunan"})

    Statistik deskriptif

    df.describe()

    Evaluasi Lazy vs Eager

    Evaluasi lazy adalah salah satu fitur paling kuat dari Polars. Fitur ini membangun rencana query yang dioptimasi sebelum dieksekusi:

    import polars as pl
    
    

    EAGER: operasi langsung dieksekusi

    df = pl.readcsv("filebesar.csv")

    result = df.filter(pl.col("jumlah") > 100).select("id", "jumlah").sort("jumlah")

    LAZY: membangun rencana query, mengoptimasi, lalu mengeksekusi

    result = (

    pl.scancsv("filebesar.csv") # Mengembalikan LazyFrame

    .filter(pl.col("jumlah") > 100)

    .select("id", "jumlah")

    .sort("jumlah")

    .collect() # Memicu eksekusi

    )

    Inspeksi rencana query

    querylazy = (

    pl.scancsv("filebesar.csv")

    .filter(pl.col("jumlah") > 100)

    .select("id", "jumlah")

    .sort("jumlah")

    )

    Lihat rencana yang dioptimasi

    print(querylazy.explain()) # Rencana yang dioptimasi

    print(querylazy.explain(optimized=False)) # Rencana tanpa optimasi

    Optimizer melakukan beberapa transformasi:

    • Predicate pushdown: Filter didorong sedini mungkin
    • Projection pushdown: Hanya kolom yang diperlukan yang dibaca dari disk
    • Type coercion: Optimasi tipe data otomatis
    • Common subexpression elimination: Menggunakan kembali hasil yang sudah dihitung

    # Contoh: Optimizer hanya akan membaca kolom "id" dan "jumlah" dari CSV
    

    dan menerapkan filter saat membaca, bukan setelah memuat seluruh file

    result = (

    pl.scancsv("filebesar.csv")

    .filter(pl.col("jumlah") > 100)

    .select("id", "jumlah")

    .collect()

    )

    Ekspresi dan Transformasi

    Ekspresi adalah blok bangunan inti dari operasi Polars:

    import polars as pl
    
    

    df = pl.DataFrame({

    "produk": ["A", "B", "A", "C", "B", "A", "C", "B"],

    "kuantitas": [10, 20, 15, 5, 25, 30, 10, 15],

    "harga": [9.99, 14.99, 9.99, 24.99, 14.99, 9.99, 24.99, 14.99],

    "wilayah": ["Utara", "Selatan", "Utara", "Timur", "Selatan", "Timur", "Utara", "Timur"]

    })

    Ekspresi kolom

    result = df.select(

    pl.col("produk"),

    pl.col("kuantitas"),

    (pl.col("kuantitas") pl.col("harga")).alias("pendapatan"),

    pl.col("kuantitas").sum().alias("totalkuantitas"),

    pl.col("kuantitas").mean().alias("ratakuantitas"),

    pl.col("kuantitas").std().alias("stdkuantitas"),

    )

    Ekspresi string

    dfstring = pl.DataFrame({

    "teks": ["Halo Dunia", "foo bar baz", "POLARS SANGAT CEPAT", "ilmu data"]

    })

    result = dfstring.select(

    pl.col("teks"),

    pl.col("teks").str.tolowercase().alias("hurufkecil"),

    pl.col("teks").str.touppercase().alias("hurufbesar"),

    pl.col("teks").str.split(" ").alias("kata"),

    pl.col("teks").str.lenchars().alias("jumlahkarakter"),

    pl.col("teks").str.contains("(?i)dunia|cepat").alias("cocokpola"),

    pl.col("teks").str.replaceall(" ", "").alias("dengangarisbawah"),

    )

    Ekspresi kondisional (when/then/otherwise)

    result = df.withcolumns(

    pl.when(pl.col("kuantitas") > 20)

    .then(pl.lit("Tinggi"))

    .when(pl.col("kuantitas") > 10)

    .then(pl.lit("Sedang"))

    .otherwise(pl.lit("Rendah"))

    .alias("tingkatpermintaan")

    )

    Ekspresi list/array

    dflist = pl.DataFrame({

    "tag": [["python", "rust"], ["java", "python"], ["rust", "go", "python"]],

    "skor": [[90, 85, 92], [78, 88], [95, 91, 87, 93]]

    })

    result = dflist.select(

    pl.col("tag").list.len().alias("jumlahtag"),

    pl.col("tag").list.contains("python").alias("punyapython"),

    pl.col("skor").list.mean().alias("rataskor"),

    pl.col("skor").list.max().alias("skormaks"),

    pl.col("skor").list.sort().alias("skorterurut"),

    )

    Ekspresi tanggal/waktu

    dftanggal = pl.DataFrame({

    "timestamp": pl.daterange(pl.date(2024, 1, 1), pl.date(2024, 12, 31), eager=True),

    }).withcolumns(

    pl.col("timestamp").dt.year().alias("tahun"),

    pl.col("timestamp").dt.month().alias("bulan"),

    pl.col("timestamp").dt.weekday().alias("harikerja"),

    pl.col("timestamp").dt.quarter().alias("kuartal"),

    pl.col("timestamp").dt.isleapyear().alias("tahunkabisat"),

    )

    Join dan Penggabungan DataFrame

    # Contoh DataFrame
    

    pesanan = pl.DataFrame({

    "idpesanan": [1, 2, 3, 4, 5],

    "idpelanggan": [101, 102, 101, 103, 104],

    "idproduk": ["P1", "P2", "P3", "P1", "P2"],

    "jumlah": [250.0, 150.0, 300.0, 250.0, 150.0]

    })

    pelanggan = pl.DataFrame({

    "idpelanggan": [101, 102, 103, 105],

    "nama": ["Alice", "Bob", "Charlie", "Eve"],

    "tingkat": ["Gold", "Silver", "Gold", "Bronze"]

    })

    produk = pl.DataFrame({

    "idproduk": ["P1", "P2", "P3"],

    "namaproduk": ["Widget", "Gadget", "Doohickey"],

    "kategori": ["Elektronik", "Elektronik", "Perkakas"]

    })

    Inner join

    result = pesanan.join(pelanggan, on="idpelanggan", how="inner")

    Left join

    result = pesanan.join(pelanggan, on="idpelanggan", how="left")

    Join bertingkat

    result = (

    pesanan

    .join(pelanggan, on="idpelanggan", how="left")

    .join(produk, on="idproduk", how="left")

    )

    Join dengan nama kolom berbeda

    dfa = pl.DataFrame({"ida": [1, 2, 3], "nilaia": [10, 20, 30]})

    dfb = pl.DataFrame({"idb": [1, 2, 4], "nilaib": [100, 200, 400]})

    result = dfa.join(dfb, lefton="ida", righton="idb", how="outer")

    Cross join

    ukuran = pl.DataFrame({"ukuran": ["S", "M", "L"]})

    warna = pl.DataFrame({"warna": ["Merah", "Biru"]})

    kombinasi = ukuran.join(warna, how="cross")

    Semi join (pertahankan baris dari kiri yang memiliki kecocokan di kanan)

    pelangganaktif = pesanan.join(pelanggan, on="idpelanggan", how="semi")

    Anti join (pertahankan baris dari kiri yang TIDAK memiliki kecocokan di kanan)

    pesanantanpapelanggan = pesanan.join(pelanggan, on="idpelanggan", how="anti")

    Penggabungan vertikal

    df1 = pl.DataFrame({"a": [1, 2], "b": [3, 4]})

    df2 = pl.DataFrame({"a": [5, 6], "b": [7, 8]})

    gabungan = pl.concat([df1, df2])

    Penggabungan horizontal

    gabunganh = pl.concat([df1, df2], how="horizontal")

    Group By dan Agregasi

    penjualan = pl.DataFrame({
    

    "tanggal": ["2024-01-15", "2024-01-15", "2024-02-10", "2024-02-10",

    "2024-03-05", "2024-03-05", "2024-01-20", "2024-02-25"],

    "produk": ["A", "B", "A", "B", "A", "B", "C", "C"],

    "wilayah": ["Utara", "Selatan", "Utara", "Selatan", "Utara", "Selatan", "Timur", "Timur"],

    "kuantitas": [100, 150, 200, 120, 180, 90, 50, 75],

    "pendapatan": [1000, 2250, 2000, 1800, 1800, 1350, 1250, 1875]

    })

    Group by sederhana

    result = penjualan.groupby("produk").agg(

    pl.col("kuantitas").sum().alias("totalkuantitas"),

    pl.col("pendapatan").sum().alias("totalpendapatan"),

    pl.col("pendapatan").mean().alias("ratapendapatan"),

    pl.len().alias("jumlahtransaksi"),

    )

    Group by dengan banyak kolom

    result = penjualan.groupby("produk", "wilayah").agg(

    pl.col("kuantitas").sum().alias("totalkuantitas"),

    pl.col("pendapatan").sum().alias("totalpendapatan"),

    )

    Agregasi lanjutan

    result = penjualan.groupby("produk").agg(

    pl.col("kuantitas").sum().alias("totalqty"),

    pl.col("pendapatan").sum().alias("totalpend"),

    pl.col("pendapatan").min().alias("minpend"),

    pl.col("pendapatan").max().alias("makspend"),

    pl.col("pendapatan").std().alias("stdpend"),

    pl.col("pendapatan").quantile(0.75).alias("q75pend"),

    pl.col("wilayah").nunique().alias("wilayahdilayani"),

    pl.col("tanggal").first().alias("penjualanpertama"),

    pl.col("tanggal").last().alias("penjualanterakhir"),

    )

    Group by dengan pengurutan

    result = (

    penjualan

    .groupby("produk")

    .agg(pl.col("pendapatan").sum().alias("totalpendapatan"))

    .sort("totalpendapatan", descending=True)

    )

    Group by dinamis (berbasis waktu)

    penjualants = penjualan.withcolumns(pl.col("tanggal").str.todate())

    bulanan = penjualants.groupbydynamic("tanggal", every="1mo").agg(

    pl.col("pendapatan").sum().alias("pendapatanbulanan"),

    pl.col("kuantitas").sum().alias("kuantitasbulanan"),

    )

    Fungsi Window

    Fungsi window menghitung nilai di seluruh baris yang terkait dengan baris saat ini tanpa menciutkan DataFrame:

    df = pl.DataFrame({
    

    "karyawan": ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"],

    "departemen": ["Teknik", "Teknik", "Teknik", "Penjualan", "Penjualan", "Penjualan"],

    "gaji": [95000, 85000, 105000, 72000, 78000, 68000],

    "tahunmasuk": [2020, 2021, 2019, 2022, 2020, 2023]

    })

    over() - fungsi window Polars

    result = df.withcolumns(

    # Rata-rata gaji dalam setiap departemen

    pl.col("gaji").mean().over("departemen").alias("ratagajidept"),

    # Peringkat dalam departemen berdasarkan gaji

    pl.col("gaji").rank(descending=True).over("departemen").alias("peringkatgaji"),

    # Gaji minimum dan maksimum di departemen

    pl.col("gaji").min().over("departemen").alias("gajimindept"),

    pl.col("gaji").max().over("departemen").alias("gajimaksdept"),

    # Jumlah karyawan di departemen

    pl.len().over("departemen").alias("ukurandept"),

    # Selisih dari rata-rata departemen

    (pl.col("gaji") - pl.col("gaji").mean().over("departemen")).alias("gajivsrata"),

    )

    Fungsi window bergulir (rolling)

    datats = pl.DataFrame({

    "tanggal": pl.daterange(pl.date(2024, 1, 1), pl.date(2024, 3, 31), eager=True),

    "nilai": [float(i) + (i % 7) 3.0 for i in range(91)]

    })

    result = datats.withcolumns(

    pl.col("nilai").rollingmean(windowsize=7).alias("ratabergulir7h"),

    pl.col("nilai").rollingsum(windowsize=7).alias("jumlahbergulir7h"),

    pl.col("nilai").rollingstd(windowsize=7).alias("stdbergulir7h"),

    pl.col("nilai").shift(1).alias("nilaisebelumnya"),

    (pl.col("nilai") - pl.col("nilai").shift(1)).alias("perubahanharian"),

    ((pl.col("nilai") / pl.col("nilai").shift(1)) - 1).alias("perubahanpersen"),

    )

    Operasi kumulatif

    result = df.sort("gaji").withcolumns(

    pl.col("gaji").cumsum().alias("gajikumulatif"),

    pl.col("gaji").cummax().alias("maksberjalan"),

    pl.col("gaji").cummin().alias("minberjalan"),

    pl.col("gaji").cumcount().alias("hitunganberjalan"),

    )

    Benchmark Polars vs Pandas

    import polars as pl
    

    import pandas as pd

    import numpy as np

    import time

    def perbandinganbenchmark(jumlahbaris: int = 10000000):

    # Buat data uji

    np.random.seed(42)

    data = {

    "id": np.arange(jumlahbaris),

    "kategori": np.random.choice(["A", "B", "C", "D", "E"], jumlahbaris),

    "nilai1": np.random.randn(jumlahbaris),

    "nilai2": np.random.randn(jumlahbaris),

    "nilai3": np.random.uniform(0, 1000, jumlahbaris),

    }

    # Pandas

    pdf = pd.DataFrame(data)

    mulai = time.time()

    pdfresult = (

    pdf.groupby("kategori")

    .agg({"nilai1": "mean", "nilai2": "sum", "nilai3": ["min", "max", "std"]})

    )

    waktupandas = time.time() - mulai

    # Polars

    pldf = pl.DataFrame(data)

    mulai = time.time()

    plresult = pldf.groupby("kategori").agg(

    pl.col("nilai1").mean(),

    pl.col("nilai2").sum(),

    pl.col("nilai3").min().alias("nilai3min"),

    pl.col("nilai3").max().alias("nilai3maks"),

    pl.col("nilai3").std().alias("nilai3std"),

    )

    waktupolars = time.time() - mulai

    print(f"Ukuran data: {jumlahbaris:,} baris")

    print(f"Pandas: {waktupandas:.3f}d")

    print(f"Polars: {waktupolars:.3f}d")

    print(f"Percepatan: {waktupandas / waktupolars:.1f}x")

    # Benchmark filter

    mulai = time.time()

    = pdf[(pdf["nilai1"] > 0) & (pdf["nilai3"] < 500)]

    filterpandas = time.time() - mulai

    mulai = time.time()

    = pldf.filter((pl.col("nilai1") > 0) & (pl.col("nilai3") < 500))

    filterpolars = time.time() - mulai

    print(f"\nBenchmark filter:")

    print(f"Pandas: {filterpandas:.3f}d")

    print(f"Polars: {filterpolars:.3f}d")

    print(f"Percepatan: {filterpandas / filterpolars:.1f}x")

    # Benchmark pengurutan

    mulai = time.time()

    = pdf.sortvalues(["kategori", "nilai1"])

    sortpandas = time.time() - mulai

    mulai = time.time()

    = pldf.sort(["kategori", "nilai1"])

    sortpolars = time.time() - mulai

    print(f"\nBenchmark pengurutan:")

    print(f"Pandas: {sortpandas:.3f}d")

    print(f"Polars: {sortpolars:.3f}d")

    print(f"Percepatan: {sortpandas / sortpolars:.1f}x")

    perbandinganbenchmark(10000000)

    Integrasi Pipeline ML

    import polars as pl
    

    import numpy as np

    from sklearn.modelselection import traintestsplit

    from sklearn.preprocessing import StandardScaler

    from sklearn.ensemble import RandomForestClassifier

    from sklearn.metrics import classificationreport

    Muat dan persiapkan data dengan Polars

    df = pl.readcsv("datapelanggan.csv")

    Rekayasa fitur dengan Polars

    dffitur = df.withcolumns(

    # Transformasi numerik

    pl.col("jumlahpembelian").log().alias("logpembelian"),

    (pl.col("jumlahpembelian") / pl.col("kunjungan")).alias("ratapembelianperkunjungan"),

    pl.col("harisejakpembelianterakhir").clip(0, 365).alias("resensidibatasi"),

    # Encoding kategorikal

    pl.col("wilayah").cast(pl.Categorical).alias("wilayahkat"),

    # Fitur berbasis waktu

    pl.col("tanggaldaftar").str.todate().dt.year().alias("tahundaftar"),

    pl.col("tanggaldaftar").str.todate().dt.month().alias("bulandaftar"),

    # Fitur berbasis grup

    pl.col("jumlahpembelian").mean().over("wilayah").alias("ratapembelianwilayah"),

    pl.col("jumlahpembelian").rank().over("wilayah").alias("peringkatdiwilayah"),

    )

    Tentukan fitur dan target

    kolomfitur = [

    "logpembelian", "ratapembelianperkunjungan", "resensidibatasi",

    "tahundaftar", "bulandaftar", "ratapembelianwilayah",

    "peringkatdiwilayah", "kunjungan", "umur"

    ]

    Konversi ke numpy untuk sklearn

    X = dffitur.select(kolomfitur).tonumpy()

    y = dffitur.select("churn").tonumpy().flatten()

    Bagi data

    Xtrain, Xtest, ytrain, ytest = traintestsplit(X, y, testsize=0.2, randomstate=42)

    Skalakan fitur

    scaler = StandardScaler()

    Xtrainscaled = scaler.fittransform(Xtrain)

    Xtestscaled = scaler.transform(Xtest)

    Latih model

    clf = RandomForestClassifier(nestimators=100, randomstate=42, njobs=-1)

    clf.fit(Xtrainscaled, ytrain)

    Evaluasi

    ypred = clf.predict(Xtestscaled)

    print(classificationreport(ytest, ypred))

    Kepentingan fitur kembali di Polars

    dfkepentingan = pl.DataFrame({

    "fitur": kolomfitur,

    "kepentingan": clf.featureimportances

    }).sort("kepentingan", descending=True)

    print(dfkepentingan)

    Menangani Dataset Besar dengan Streaming

    Polars dapat menangani dataset yang lebih besar dari RAM yang tersedia melalui streaming:

    import polars as pl
    
    

    Streaming: proses data dalam potongan tanpa memuat semuanya ke memori

    result = (

    pl.scancsv("datasetsangatbesar.csv") # Tidak dimuat ke memori

    .filter(pl.col("status") == "aktif")

    .groupby("kategori")

    .agg(

    pl.col("jumlah").sum().alias("totaljumlah"),

    pl.col("jumlah").mean().alias("ratajumlah"),

    pl.len().alias("hitungan")

    )

    .sort("totaljumlah", descending=True)

    .collect(streaming=True) # Proses dalam mode streaming

    )

    Scan file Parquet (lebih efisien lagi)

    result = (

    pl.scanparquet("data/.parquet") # Pola glob untuk banyak file

    .filter(pl.col("tahun") >= 2023)

    .select("id", "kategori", "jumlah", "tahun")

    .collect(streaming=True)

    )

    Tulis hasil langsung ke file (tidak pernah mewujudkan hasil penuh di memori)

    (

    pl.scancsv("inputbesar.csv")

    .filter(pl.col("nilai") > 0)

    .withcolumns(

    (pl.col("nilai") 2).alias("nilaiganda")

    )

    .sinkparquet("outputdiproses.parquet")

    )

    Proses banyak file besar secara efisien

    import glob

    lazyframes = [pl.scanparquet(f) for f in glob.glob("data/bagian.parquet")]

    gabungan = pl.concat(lazyframes)

    result = (

    gabungan

    .groupby("idpelanggan")

    .agg(

    pl.col("jumlahpembelian").sum().alias("nilaiseumurhidup"),

    pl.col("tanggalpembelian").max().alias("pembelianterakhir"),

    pl.len().alias("totalpesanan")

    )

    .filter(pl.col("nilaiseumurhidup") > 1000)

    .sort("nilaiseumurhidup", descending=True)

    .head(1000)

    .collect(streaming=True)

    )

    Konversi CSV besar ke Parquet untuk performa lebih baik

    (

    pl.scancsv("datalama.csv")

    .sinkparquet(

    "datalama.parquet",

    compression="zstd",

    rowgroupsize=100000

    )

    )

    Praktik Terbaik

  • Gunakan Evaluasi Lazy: Selalu pilih scan daripada read untuk dataset besar. Biarkan optimizer bekerja.
  • Pilih Parquet: File Parquet bersifat kolumnar, terkompresi, dan mendukung predicate/projection pushdown. Selalu konversi CSV ke Parquet untuk analisis berulang.
  • Hindari Operasi Berbasis Baris: Berpikir dalam kolom, bukan baris. Gunakan ekspresi daripada apply() atau maprows() kapan pun memungkinkan.
  • Rantai Operasi: Bangun rantai ekspresi yang panjang daripada membuat DataFrame perantara. Ini memungkinkan optimasi yang lebih baik.
  • Gunakan Tipe Data yang Tepat: Konversi kolom ke tipe terkecil yang sesuai. Gunakan pl.Categorical untuk kolom string dengan sedikit nilai unik.
  • Manfaatkan over() untuk Fungsi Window: Daripada self-join atau operasi merge, gunakan over() untuk komputasi tingkat grup.
  • Profil Query Anda: Gunakan explain() untuk memeriksa rencana query dan mengidentifikasi bottleneck.
  • Manajemen Memori: Gunakan mode streaming untuk dataset yang lebih besar dari RAM. Tulis hasil langsung ke disk jika memungkinkan.
  • Gunakan Tipe struct dan list: Polars secara native mendukung tipe data bersarang, menghindari kebutuhan workaround yang kompleks.
  • Paralelkan I/O: Saat membaca banyak file, gunakan scanparquet dengan pola glob untuk membiarkan Polars memparalelkan pembacaan.
  • Kesimpulan

    Polars merupakan kemajuan signifikan dalam ekosistem pemrosesan data Python. Mesin berbasis Rust, evaluasi lazy dengan optimasi query, dan dukungan streaming yang mulus menjadikannya pilihan ideal untuk beban kerja analitis maupun pipeline data produksi. Dengan mengadopsi praktik terbaik Polars -- evaluasi lazy, format file Parquet, pemikiran kolumnar, dan streaming -- Anda dapat memproses dataset dengan kecepatan berlipat ganda dibandingkan dengan alat tradisional, sambil menggunakan memori yang jauh lebih sedikit. Untuk proyek baru, Polars seharusnya menjadi library DataFrame default Anda.

    Artikel Terkait

    Tutorial Ibis: API DataFrame Portabel untuk Banyak Backend

    Ibis: API Dataframe Python yang Portabel di Banyak Backend Ibis adalah library dataframe Python yang memungkinkan Anda m...

    Tutorial Marimo: Notebook Python Reaktif dan Reproducible

    Marimo: Notebook Python yang Reaktif dan Reproducible Marimo adalah notebook Python yang menyimpan isinya sebagai berkas...

    Tutorial Kedro: Pipeline Data Science yang Reproducible dan Terstruktur

    Kedro: Pipeline Data Science yang Reproducible dan Mudah Dirawat Sebagian besar proyek data science dimulai dari satu no...

    DuckDB: Database Analitik In-Process untuk Data Science

    DuckDB: Database Analitik In-Process untuk Data Science DuckDB adalah database analitik in-process yang dirancang khusus...