Pandas & NumPy Academy · Lezione

Parquet: archiviazione colonnare veloce

Scriva un DataFrame Pandas in Parquet con to_parquet(), lo rilegga più velocemente rispetto a un CSV e usi il column pruning per caricare solo i campi necessari.

Lezione 4 di 413 passaggi

Parquet: archiviazione colonnare veloce è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.

Che cos'è Parquet

Apache Parquet è un formato di file binario colonnare progettato per i carichi di lavoro analitici. A differenza del CSV, che memorizza i dati riga per riga come testo, Parquet memorizza ogni colonna in un blocco contiguo, la comprime in modo efficiente e codifica i metadati. Questo lo rende notevolmente più veloce per le query che leggono solo alcune colonne da una tabella con molte colonne. Parquet è il formato standard di fatto nei data lake (AWS S3, Google Cloud Storage) ed è supportato nativamente da Pandas, Dask, Spark e BigQuery.

Scrittura di Parquet con to_parquet()

La conversione di un DataFrame Pandas in Parquet richiede una sola chiamata di metodo: df.to_parquet('output.parquet'). Il motore predefinito è pyarrow (installabile con pip install pyarrow). Parquet conserva esattamente i tipi delle colonne: non è più necessario che le colonne di date vengano rilette come stringhe. Supporta inoltre la compressione senza configurazioni aggiuntive tramite il parametro compression; 'snappy' offre lettura e scrittura rapide con una compressione moderata, mentre 'gzip' garantisce una compressione maggiore a scapito della velocità.

import pandas as pd
import numpy as np

# Create a sample DataFrame
np.random.seed(0)
df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=100000, freq='T'),
    'value': np.random.randn(100000),
    'category': np.random.choice(['A', 'B', 'C'], 100000)
})

# Write to Parquet
df.to_parquet('data.parquet', index=False, compression='snappy')
print('Written to data.parquet')

Lettura di Parquet con read_parquet()

pd.read_parquet('output.parquet') rilegge il file in un DataFrame. Rispetto alla lettura del CSV equivalente, Parquet è in genere da 5 a 10 volte più veloce per le tabelle con molte colonne. I tipi vengono preservati esattamente: le date rimangono datetime64, le categorie rimangono category e gli interi rimangono int32 o int64, come memorizzati. Non è necessaria alcuna inferenza dei tipi, perché i metadati sono incorporati nel file.

import pandas as pd
import time

# Read Parquet
start = time.time()
df = pd.read_parquet('data.parquet')
print(f'Read Parquet: {time.time()-start:.3f}s')
print(df.dtypes)
print(df.shape)

Potatura delle colonne: lettura delle sole colonne necessarie

Il vantaggio principale dell'archiviazione colonnare è la potatura delle colonne: è possibile leggere solo colonne specifiche senza analizzare il resto del file. Passi un elenco di nomi di colonne al parametro columns. Se una tabella con 100 colonne occupa 100 MB per colonna e ne servono solo 3, Parquet legge 3 MB invece di 10 GB. Il CSV deve analizzare ogni carattere per estrarre una qualsiasi colonna. Questo rende Parquet ideale per le tabelle con molte colonne nelle pipeline analitiche.

import pandas as pd

# Only load the 2 columns needed for this analysis
df = pd.read_parquet('large_table.parquet',
                     columns=['date', 'revenue'])
print(df.columns.tolist())
print(df.shape)
print(df.memory_usage(deep=True).sum() / 1e6, 'MB loaded')

Filtraggio dei gruppi di righe (predicate pushdown)

Parquet memorizza le statistiche (minimo/massimo) per ogni gruppo di righe (un blocco di righe) nel footer del file. Quando si applica un filtro tramite il parametro filters, il lettore salta interi gruppi di righe in cui il filtro non può trovare corrispondenze: questa tecnica si chiama predicate pushdown. Per esempio, filtrando le date in un file Parquet ordinato temporalmente, vengono saltati interi blocchi mensili fuori dall'intervallo e vengono lette solo le parti pertinenti. Il motore pyarrow supporta questa funzionalità nativamente.

import pandas as pd

# Filter using predicate pushdown — row groups outside range are skipped
df = pd.read_parquet(
    'time_series.parquet',
    columns=['date', 'value'],
    filters=[('date', '>=', '2024-06-01'),
              ('date', '<', '2024-07-01')]
)
print(f'Loaded {len(df):,} rows (June only)')
print(df.head())

Parquet e CSV: un confronto

Ecco un confronto pratico tra Parquet e CSV per un dataset di 10 milioni di righe e 20 colonne:

  • Dimensione del file: CSV ~2 GB, Parquet (snappy) ~400 MB
  • Tempo di lettura (tutte le colonne): CSV ~15 s, Parquet ~2 s
  • Tempo di lettura (3 colonne): CSV ~15 s (deve analizzarle tutte), Parquet ~0,3 s
  • Conservazione dei tipi: il CSV perde i tipi, Parquet li conserva
  • Leggibilità per le persone: CSV sì, Parquet no (binario)

Per le pipeline di produzione, in cui i dati vengono scritti una volta e letti molte volte, Parquet è quasi sempre la scelta migliore.

Dataset Parquet partizionati

Per i dataset di grandi dimensioni, Parquet supporta i dataset partizionati: i dati vengono suddivisi in più file organizzati in una gerarchia di directory in base ai valori delle colonne. Per esempio, il partizionamento per anno e mese crea data/year=2024/month=01/part.parquet. La lettura di un dataset partizionato filtra automaticamente le directory corrispondenti a una query. Questo è il layout standard nei data lake e consente query efficienti su intervalli che riguardano miliardi di righe.

import pandas as pd

# Write a partitioned dataset (requires pyarrow)
df = pd.read_parquet('all_data.parquet')
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month

df.to_parquet(
    'partitioned_data/',
    partition_cols=['year', 'month'],
    index=False
)
# Creates: partitioned_data/year=2024/month=1/part-0.parquet etc.

Lettura di dataset partizionati

La lettura di una directory Parquet partizionata è identica alla lettura di un singolo file: Pandas (tramite pyarrow) individua automaticamente tutti i file delle partizioni. I valori della colonna di partizionamento vengono inclusi come colonne nel DataFrame risultante. È inoltre possibile usare filters per sfruttare la potatura delle partizioni, che salta interi sottoalberi di directory in base ai valori della colonna di partizionamento. In questo modo, interrogare un dataset partizionato di 1 TB può sembrare come leggere pochi MB.

import pandas as pd

# Read the entire partitioned dataset
df_all = pd.read_parquet('partitioned_data/')
print('All years:', df_all['year'].unique())

# Read only 2024 data using partition pruning
df_2024 = pd.read_parquet(
    'partitioned_data/',
    filters=[('year', '==', 2024)]
)
print('2024 rows:', len(df_2024))

Parquet con Dask

Dask legge e scrive nativamente Parquet con dd.read_parquet() e ddf.to_parquet(). Ogni file in una directory Parquet partizionata diventa una partizione Dask, consentendo letture completamente parallele. Dask sfrutta inoltre il predicate pushdown quando vengono specificati i filtri. Scrivere un risultato Dask di grandi dimensioni in un dataset Parquet partizionato è il modo standard per produrre output nelle moderne pipeline di data engineering.

import dask.dataframe as dd

# Read partitioned Parquet with Dask (each file = one partition)
ddf = dd.read_parquet('partitioned_data/',
                      columns=['date', 'revenue', 'region'],
                      filters=[('year', '==', 2024)])

# Compute aggregation in parallel
result = ddf.groupby('region')['revenue'].sum().compute()
print(result.sort_values(ascending=False))

Opzioni di compressione e codifica

Parquet supporta diversi algoritmi di compressione e schemi di codifica interni. Snappy (predefinito) privilegia la velocità con una compressione moderata. Gzip produce file più piccoli di circa il 30%, ma è più lento in lettura e scrittura. Zstd offre un equilibrio tra velocità e compressione migliore rispetto a entrambi. Per le colonne intere, Parquet applica automaticamente la codifica delta o la codifica a dizionario per ridurre ulteriormente le dimensioni, senza richiedere alcuna configurazione aggiuntiva da parte Sua.

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({'id': range(500000), 'val': np.random.randn(500000)})

for comp in ['snappy', 'gzip', 'zstd']:
    fname = f'data_{comp}.parquet'
    df.to_parquet(fname, compression=comp, index=False)
    import os
    size_mb = os.path.getsize(fname) / 1e6
    print(f'{comp}: {size_mb:.2f} MB')

Sostituire CSV nella pipeline

Il modo più semplice per adottare Parquet consiste nell'aggiungere un passaggio di conversione una tantum all'inizio del progetto: legga il CSV una volta, pulisca i dati e converta i tipi, quindi salvi il risultato in formato Parquet. Tutte le esecuzioni successive leggeranno il file Parquet invece del CSV. In questo modo otterrà immediatamente vantaggi in termini di velocità e spazio di archiviazione, con modifiche minime al codice. Per i nuovi dati che arrivano in formato CSV (ad esempio, esportazioni notturne), aggiunga alla pipeline un passaggio di conversione che scriva in Parquet prima dell'inizio di qualsiasi analisi.

import pandas as pd

# One-time conversion
df = pd.read_csv('raw_data.csv',
                 parse_dates=['date'],
                 dtype={'category': 'category',
                        'amount': 'float32'})
df.to_parquet('clean_data.parquet', index=False)

# All future reads use Parquet
df_fast = pd.read_parquet('clean_data.parquet')
print('Loaded from Parquet:', df_fast.dtypes.to_dict())

Verifica rapida

Verifichi la Sua comprensione dei concetti di analisi dei dati presentati in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato che to_parquet() e read_parquet() consentono operazioni di I/O sui file più veloci, file più piccoli e la conservazione dei tipi di dati rispetto a CSV; il pruning delle colonne con il parametro columns legge solo le colonne necessarie, evitando la scansione dell'intero file; e i dataset Parquet partizionati, organizzati in base ai valori delle colonne, consentono il pruning delle partizioni per eseguire in modo efficiente query su intervalli in grandi data lake. Nel prossimo capitolo collegheremo Pandas ai database relazionali usando SQLAlchemy.

Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Parquet: archiviazione colonnare veloce» è gratuita?

Sì — il testo completo di «Parquet: archiviazione colonnare veloce» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.

Cosa imparerò in «Parquet: archiviazione colonnare veloce»?

Scriva un DataFrame Pandas in Parquet con to_parquet(), lo rilegga più velocemente rispetto a un CSV e usi il column pruning per caricare solo i campi necessari. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?

Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Parquet: archiviazione colonnare veloce»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?

Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. CSV in streaming con chunksize
  2. Aggregazione incrementale tra i blocchi
  3. Introduzione ai DataFrame Dask
  4. Parquet: archiviazione colonnare veloce
← Torna a Pandas & NumPy Academy