Python, de la zero Lecția 25 / 60

Pandas în 2026: ce să știi, ce să sari, ascensiunea Polars

Unde stă pandas în ecosistemul de date din 2026, backend-ul PyArrow, și când câștigă cu adevărat Polars.

Bine ai venit la Modulul 5. Am petrecut primele patru module pe limbaj în sine și pe tooling-ul din jurul lui; acum schimbăm vitezele și petrecem următoarele zece lecții pe ce fac efectiv majoritatea dezvoltatorilor Python care lucrează zi de zi cu limbajul, adică să împingă date tabulare prin transformări. Aproximativ jumătate din joburile Python pe care le-am văzut în ultimul deceniu erau, fundamental, „citește un fișier, modifică niște coloane, scrie alt fișier, trimite un mesaj pe Slack când se rupe.” Munca aia rulează pe pandas. Modulul 5 este măiestria pandas; Modulul 6 e partea mai grea (window functions, time series, performanță). Lecția 35 este un capitol dedicat pentru Polars, pe care îl vom întâlni pe scurt astăzi.

Dar înainte să atingem un read_csv, trebuie să discutăm unde stă pandas în 2026, ce s-a schimbat în ultimii trei ani, și de ce vechile răspunsuri de pe StackOverflow ți-ar putea da sfaturi cu care biblioteca nu mai e de acord.

O scurtă istorie, fiindcă contextul contează

Pandas a fost început de Wes McKinney în 2008 la fondul de hedging AQR. Avea nevoie de ceva între Excel și o bază de date SQL pentru date financiare cu mult time-series, a descoperit că ce exista în Python la momentul respectiv era ori NumPy (prea low-level), ori R prin rpy2 (prea greoi), și a scris al lui. L-a făcut open-source anul următor, a plecat din finanțe, și a petrecut cea mai mare parte a două decenii păstorind ecosistemul de date. (A demarat și proiectul Apache Arrow în 2016, ține minte asta, va conta în cinci paragrafe.)

Vreo cincisprezece ani, pandas era răspunsul la „am un tabel în Python.” Nu singurul răspuns, existau mereu alternative, de la dask pentru date out-of-core până la PySpark pentru scară de cluster, dar răspunsul implicit, lucrul după care întindea mâna fiecare notebook de pe Kaggle și fiecare laptop de data scientist junior. Fiecare bibliotecă adiacentă era construită să accepte un DataFrame pandas: df.plot() de la matplotlib, fit(X, y) de la scikit-learn unde X este de obicei un DataFrame, statsmodels, seaborn, plotly, wrapper-ele SQL-via-DataFrame, conectorii pentru baze de date. Șanțul ecosistemic e enorm, iar asta contează pentru ce vom discuta într-o clipă.

Problemele erau mereu aceleași. Pandas era construit peste NumPy, care nu avea un concept nativ de valori lipsă pentru coloane de întregi sau booleene (deci o coloană cu un singur întreg lipsă devenea float64, cu valoarea lipsă ca NaN, surprinzător și greșit). Coloanele de string erau stocate ca obiecte Python în array-ul NumPy, ceea ce însemna operații pe string-uri lente și memorie umflată. Semantica default de copy-on-write era inconsistentă, uneori primeai un view, alteori o copie, iar faimosul SettingWithCopyWarning bântuia pe toată lumea. Niciuna nu era fatală, dar se acumulau.

Pandas 2.0 (2023), rescrierea liniștită

Pandas 2.0 a apărut în aprilie 2023 și e cel mai consecvent release de la 1.0. Schimbarea de pe prima pagină: un backend PyArrow ca alternativă la NumPy sub capotă.

Ce înseamnă asta în practică. Apache Arrow este un format de memorie pe coloane proiectat pentru workload-uri analitice. Are suport first-class pentru valori lipsă (fiecare tip e nullable), stocare eficientă a string-urilor, schimb rapid zero-copy între limbaje și unelte, și e lingua franca pe care o vorbesc DuckDB, Polars, Spark, și depozitele de date moderne. Dând lui pandas un backend Arrow, mainerii au obținut coloane de întregi nullable, operații pe string-uri de zece ori mai rapide, și un format de memorie partajat cu restul lumii datelor, fără să rupă milioanele de linii de cod pandas existente.

Trei lucruri de știut despre el la mai 2026:

Este opt-in. Citirea unui CSV cu pd.read_csv("file.csv") îți dă tot backend-ul NumPy. Ceri Arrow explicit:

import pandas as pd

df = pd.read_csv("sales.csv", dtype_backend="pyarrow")
df = pd.read_parquet("sales.parquet", dtype_backend="pyarrow")

# Or globally for a script
pd.options.future.infer_string = True  # arrow-backed strings by default

Este matur acum. Primul an al backend-ului Arrow (2023) avea margini aspre, unele operații cădeau pe NumPy și copiau date, unele nu mergeau deloc. Până la pandas 2.2 (începutul lui 2024) majoritatea acelor probleme erau închise, iar la seria 2.3 din 2025 backend-ul este stabil pentru operațiile pe care le folosește un analist obișnuit. Dacă pornești un proiect nou în 2026, pandas cu Arrow este default-ul corect.

Copy-on-write este noul default, și e o îmbunătățire reală. Vechiul footgun „e asta un view sau o copie?” a dispărut în pandas 3.0 (lansat la finalul lui 2025), iar acum în 2.x îl poți activa cu pd.options.mode.copy_on_write = True. Cod nou; default-uri noi; pornește-l.

Polars, alternativa în ascensiune

În timp ce pandas își rescria instalațiile, Polars era scris de la zero în Rust de Ritchie Vink. Prima versiune a aterizat în 2020; versiunea 1.0 la mijlocul lui 2024; până la mai 2026 e la 1.x și suficient de stabil pentru producție. E cel mai credibil contracandidat pe care l-a avut pandas de când a început era modernă.

Argumentul e ușor: Polars e construit pe Arrow din ziua unu (fără moșteniri NumPy), e multi-threaded by default, are un query optimizer (modul lazy planifică tot pipeline-ul tău înainte de a-l executa), și e scris într-un limbaj de sisteme deci buclele interne nu plătesc taxa de interpretor a Python-ului. Pe majoritatea operațiilor, filtrare, join, group-by, agregare, Polars este de două până la zece ori mai rapid decât pandas cu backend-ul Arrow, și folosește semnificativ mai puțină memorie.

Are și un API mai consistent. Pandas a acumulat cincisprezece ani de decizii „să adăugăm și metoda asta”, ducând la trei moduri de a filtra rânduri, patru moduri de a adăuga o coloană, și un sistem de index sincer confuz pentru începători. Polars a făcut API-ul uniform: totul este o expresie pe o coloană, executată în contextul unui DataFrame.

Comparație rapidă de sintaxă. Grupează niște vânzări după regiune și calculează media și totalul, filtrând mai întâi tranzacțiile de valoare mare:

# pandas
import pandas as pd

df = pd.read_parquet("sales.parquet", dtype_backend="pyarrow")
result = (
    df[df["amount"] > 1000]
    .groupby("region", as_index=False)
    .agg(mean_amount=("amount", "mean"), total=("amount", "sum"))
)
# Polars
import polars as pl

df = pl.read_parquet("sales.parquet")
result = (
    df.filter(pl.col("amount") > 1000)
      .group_by("region")
      .agg(
          mean_amount=pl.col("amount").mean(),
          total=pl.col("amount").sum(),
      )
)

Modul lazy este unde Polars trage cu adevărat înainte: pl.scan_parquet în loc de pl.read_parquet, iar motorul planifică tot calculul, împinge filtrele în jos până la cititorul de fișier, taie coloanele pe care nu le folosești, și execută doar când apelezi .collect(). O să-l vedem în lecția 35.

Deci pe care ar trebui s-o înveți?

Pe amândouă. Dar dacă ai timp doar pentru una prima, e tot pandas, și iată de ce.

Alege pandas când:

  • Restul stack-ului tău așteaptă un DataFrame. Scikit-learn, statsmodels, matplotlib, seaborn, plotly, fiecare tutorial, fiecare notebook Kaggle, fiecare manual de finanțe cantitative scris înainte de 2025, presupun că df este un pandas.DataFrame. Șanțul ecosistemic este factorul decisiv în majoritatea zilelor.
  • Faci analiză interactivă într-un notebook. Printarea mai bogată a pandas, integrarea mai bună cu Jupyter, și memoria musculară a df.head(), df.describe(), df["col"].value_counts() e greu de renunțat.
  • Datele tale încap confortabil pe o singură mașină, ceea ce de obicei înseamnă sub 50 GB de date in-memory. Pandas cu backend-ul Arrow e bine în acel interval.
  • Lucrezi cu o echipă care deja știe pandas. Costurile de tranziție sunt reale.

Alege Polars când:

  • Construiești un pipeline batch performance-critic care rulează la oră fixă. Accelerația de două până la zece ori se compune.
  • Datele tale sunt la mărimea incomodă, prea mari ca pandas să fie confortabil, prea mici ca să justifici Spark. Polars manipulează zeci de milioane de rânduri pe un laptop într-un mod cu care pandas se chinuie.
  • Este un proiect nou, fără moștenire și fără constrângerea de cunoștințe ale echipei.
  • Vrei evaluare lazy, optimizare de query-uri, și suport out-of-core direct din cutie.

Tiparul „folosește amândouă” este sincer comun în 2026. Ingestare și curățare cu Polars (fiindcă e rapid și operațiile sunt curate), apoi .to_pandas() la granița unde transmiți datele către scikit-learn sau statsmodels. Polars are un .to_pandas() zero-copy când ambele părți folosesc Arrow, deci costul e practic zero.

import polars as pl

# Heavy lifting in Polars
clean = (
    pl.scan_parquet("raw/*.parquet")
      .filter(pl.col("status") == "completed")
      .group_by("user_id")
      .agg(pl.col("amount").sum())
      .collect()
)

# Hand off to pandas for sklearn
df = clean.to_pandas(use_pyarrow_extension_array=True)

from sklearn.linear_model import LinearRegression
# ... fit a model on df ...

Ce instalăm

Pentru restul Modulului 5 și 6, vei avea nevoie de:

uv add pandas pyarrow numpy
uv add polars  # for lesson 35 (and for trying things alongside pandas)

PyArrow este o dependență obligatorie pentru backend-ul Arrow, deci adaug-o acum chiar dacă nu ești sigur că o vei folosi, jumătate din funcțiile moderne de citire o acceptă și mai multe feature-uri pandas avertizează sau eșuează fără ea.

N-ai nevoie de Numba, Cython, Dask, sau orice alt pachet „face pandas mai rapid”. Vom atinge Dask în Modulul 6 când discutăm out-of-core, dar pentru următoarele zece lecții e pandas pur, plus backend-ul Arrow, plus o pișcătură de Polars ca să-ți păstrezi perspectiva sinceră.

Ce acoperă acest modul

Următoarele zece lecții:

  • 26 Series și DataFrame, modelul de date, în sfârșit explicat.
  • 27 Citirea datelor, CSV, Parquet, Excel, JSON, SQL, capcanele.
  • 28 Selecție și filtrare, loc, iloc, măști booleene, query.
  • 29 Adăugarea și transformarea coloanelor, assign, apply, vectorizare.
  • 30 GroupBy, split-apply-combine, inima pandas.
  • 31 Joins și merges, ce așteaptă fiecare dezvoltator SQL, și capcana indexului.
  • 32 Reshaping, pivot, melt, stack, unstack, dansul long/wide.
  • 33 Date lipsă, NaN, pd.NA, povestea null-urilor din Arrow.
  • 34 String-uri și categorice, coloane de text făcute bine.
  • 35 Polars, aceleași probleme, bibliotecă diferită.

Lecția 26 e vineri: modelul de date pe care stau toate cele nouă lecții ce urmează. Sari peste el pe propriul risc; oamenii care trec în fugă peste distincția Series/DataFrame/Index își petrec restul carierei pandas confuzi.

Lectură suplimentară

Ne vedem vineri.

Caută