Ottimizza le prestazioni di BigQuery DataFrames

BigQuery DataFrames ti aiuta ad analizzare e trasformare i dati in BigQuery utilizzando un'API compatibile con pandas. Per rendere l'elaborazione dei dati più rapida ed economica, puoi utilizzare diverse tecniche per migliorare le prestazioni.

Questo documento descrive i seguenti modi per ottimizzare il rendimento:

Utilizzare la modalità di ordinamento parziale

BigQuery DataFrames ha una funzionalità di modalità di ordinamento, che impone un ordine specifico delle righe per operazioni come funzioni finestra e join. Puoi specificare la modalità di ordinamento impostando la proprietà ordering_mode su strict (nota come modalità di ordinamento esatta, che è l'impostazione predefinita) o partial (nota come modalità di ordinamento parziale). L'utilizzo dell'impostazione partial può rendere più efficienti le query.

La modalità di ordinamento parziale è diversa dalla modalità di ordinamento rigoroso. La modalità di ordinamento rigoroso dispone tutte le righe in un ordine specifico. Questo ordinamento totale consente a BigQuery DataFrames di funzionare meglio con pandas, consentendoti di accedere alle righe in base al loro ordine utilizzando la proprietà DataFrame.iloc. Tuttavia, l'ordinamento totale e il relativo indice sequenziale predefinito impediscono ai filtri su colonne o righe di ridurre la quantità di dati scansionati. Questa prevenzione si verifica a meno che tu non applichi questi filtri come parametri alle funzioni read_gbq e read_gbq_table. Per ordinare tutte le righe del DataFrame, BigQuery DataFrames crea un hash di tutte le righe. Questa operazione può causare una scansione completa dei dati che ignora i filtri di righe e colonne.

La modalità di ordinamento parziale impedisce a BigQuery DataFrames di creare un ordine totale per tutte le righe e disattiva le funzionalità che richiedono un ordine totale, come la proprietà DataFrame.iloc. La modalità di ordinamento parziale imposta anche la classe DefaultIndexKind su un indice nullo, anziché su un indice sequenziale.

Quando filtri un oggetto DataFrame utilizzando la modalità di ordinamento parziale, BigQuery DataFrames non calcola le righe mancanti nell'indice sequenziale. La modalità di ordinamento parziale non combina automaticamente i dati in base all'indice. Questi approcci possono aumentare l'efficienza delle query. Tuttavia, indipendentemente dal fatto che utilizzi la modalità di ordinamento rigoroso predefinita o la modalità di ordinamento parziale, l'API BigQuery DataFrames funziona come la nota API pandas.

Con le modalità di ordinamento parziale e rigoroso, paghi le risorse BigQuery che utilizzi. Tuttavia, l'utilizzo della modalità di ordinamento parziale può ridurre i costi quando si lavora con tabelle partizionate e in cluster di grandi dimensioni. Questa riduzione dei costi si verifica perché i filtri di riga sulle colonne di cluster e partizione riducono la quantità di dati elaborati.

Attivare la modalità di ordinamento parziale

Per utilizzare l'ordinamento parziale, imposta la proprietà ordering_mode su partial prima di eseguire qualsiasi altra operazione con BigQuery DataFrames, come mostrato nel seguente esempio di codice:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

La modalità di ordinamento parziale impedisce i join impliciti di oggetti BigQuery DataFrames non correlati perché non dispone di un indice sequenziale. Devi invece chiamare esplicitamente il metodo DataFrame.merge per unire due oggetti BigQuery DataFrames derivati da espressioni di tabelle diverse.

Le funzionalità Series.unique() e Series.drop_duplicates() non funzionano con la modalità di ordinamento parziale. Utilizza invece il metodo groupby per trovare valori univoci, come mostrato nell'esempio seguente:

# Avoid order dependency by using groupby instead of drop_duplicates.
unique_col = df.groupby(["column"], as_index=False).size().drop(columns="size")

Con la modalità di ordinamento parziale, l'output delle funzioni DataFrame.head(n) e Series.head(n) potrebbe non essere lo stesso ogni volta che le esegui. Per scaricare un piccolo campione casuale dei dati, utilizza i metodi DataFrame.peek() o Series.peek().

Per un tutorial dettagliato in cui utilizzi la proprietà ordering_mode = "partial", consulta Analizzare i download di pacchetti da PyPI con BigQuery DataFrames.

Risoluzione dei problemi

Poiché BigQuery DataFrames in modalità di ordinamento parziale a volte non dispone di un ordinamento o di un indice, potresti riscontrare i seguenti problemi quando utilizzi alcuni metodi compatibili con pandas.

Errore Ordine richiesto

Alcune funzionalità, come DataFrame.head() e DataFrame.iloc, richiedono un ordinamento. Per un elenco delle funzionalità che richiedono l'ordinamento, consulta la colonna Richiede l'ordinamento in API pandas supportate.

Quando un oggetto non ha un ordinamento, l'operazione non riesce e viene visualizzato un messaggio OrderRequiredError simile al seguente: OrderRequiredError: Op iloc requires an ordering. Use .sort_values or .sort_index to provide an ordering.

Come indicato nel messaggio di errore, puoi fornire un ordinamento utilizzando il metodo DataFrame.sort_values() per ordinare in base a una o più colonne. Altri metodi, come DataFrame.groupby(), forniscono implicitamente un ordinamento totale in base alle chiavi di raggruppamento.

Se l'ordinamento non è un ordinamento totale completamente stabile per tutte le righe, le operazioni successive potrebbero mostrare un messaggio AmbiguousWindowWarning come il seguente: AmbiguousWindowWarning: Window ordering may be ambiguous, this can cause unstable results.

Se il tuo lavoro può gestire risultati non sempre uguali o se puoi verificare manualmente che l'ordinamento sia totale, puoi filtrare il messaggio AmbiguousWindowWarning in questo modo:

import warnings

import bigframes.exceptions

warnings.simplefilter(
    "ignore", category=bigframes.exceptions.AmbiguousWindowWarning
)

Errore di indice nullo

Alcune proprietà, come DataFrame.unstack() e Series.interpolate(), richiedono un indice. Per un elenco delle funzionalità che richiedono un indice, consulta la colonna Richiede indice in API pandas supportate.

Quando utilizzi un'operazione che richiede un indice con modalità di ordinamento parziale, l'operazione genera un messaggio NullIndexError simile al seguente: NullIndexError: DataFrame cannot perform interpolate as it has no index. Set an index using set_index.

Come indicato nel messaggio di errore, puoi fornire un indice utilizzando il metodo DataFrame.set_index() per ordinare in base a una o più colonne. Altri metodi, come DataFrame.groupby(), forniscono implicitamente un indice basato sulle chiavi di raggruppamento, a meno che non sia impostato il parametro as_index=False.

Memorizza nella cache i risultati dopo operazioni costose

BigQuery DataFrames archivia le operazioni localmente e posticipa l'esecuzione delle query fino a quando non vengono soddisfatte determinate condizioni. Ciò può causare l'esecuzione delle stesse operazioni più volte in query diverse.

Per evitare di ripetere operazioni costose, salva i risultati intermedi con il metodo cache(), come mostrato nell'esempio seguente:

# Assume you have 3 large dataframes "users", "group" and "transactions"

# Expensive join operations
final_df = users.join(groups).join(transactions)
final_df.cache()
# Subsequent derived results will reuse the cached join
print(final_df.peek())
print(len(final_df[final_df["completed"]]))
print(final_df.groupby("group_id")["amount"].mean().peek(30))

Questo metodo crea una tabella BigQuery temporanea per archiviare i risultati. Ti viene addebitato un costo per l'archiviazione di questa tabella temporanea in BigQuery.

Visualizzare l'anteprima dei dati con il metodo peek()

BigQuery DataFrames offre due metodi API per visualizzare l'anteprima dei dati:

  • peek(n) restituisce n righe di dati, dove n è il numero di righe.
  • head(n) restituisce le prime n righe di dati, a seconda del contesto, dove n è il numero di righe.

Utilizza il metodo head() solo quando l'ordine dei dati è importante, ad esempio, quando vuoi i cinque valori più grandi in una colonna. In altri casi, utilizza il metodo peek() per un recupero dei dati più efficiente, come mostrato nel seguente esempio di codice:

import bigframes.pandas as bpd

# Read the "Penguins" table into a dataframe
df = bpd.read_gbq("bigquery-public-data.ml_datasets.penguins")

# Preview 3 random rows
df.peek(3)

Puoi anche utilizzare il metodo peek() per scaricare un campione di dati piccolo e casuale mentre utilizzi la modalità di ordinamento parziale.

Posticipare il recupero dei dati repr()

Puoi chiamare il metodo repr() in BigQuery DataFrames con i notebook o il debugger IDE. Questa chiamata attiva la chiamata head() che recupera i dati effettivi. Questo recupero può rallentare il processo iterativo di codifica e debug e comportare anche costi.

Per impedire al metodo repr() di recuperare i dati, imposta l'attributo repr_mode su "deferred", come mostrato nell'esempio seguente:

import bigframes.pandas as bpd

bpd.options.display.repr_mode = "deferred"

In modalità differita, puoi visualizzare l'anteprima dei dati solo con chiamate peek() e head() esplicite.

Passaggi successivi