BigQuery DataFrames-Leistung optimieren

Sie können Ihre BigQuery DataFrames-Workflows optimieren, um Daten mit einer pandas-kompatiblen API zu analysieren und zu transformieren, während die Ausführungszeiten und Kosten niedrig bleiben. Durch die Anwendung bestimmter Optimierungstechniken, z. B. des Modus für die partielle Sortierung und des Ergebnis-Caching, können Sie Daten schneller und kostengünstiger verarbeiten.

Modus für partielle Sortierung verwenden

BigQuery DataFrames bietet eine Sortiermodus-Funktion, die eine bestimmte Zeilenreihenfolge für Vorgänge wie Fensterfunktionen und Joins erzwingt. Sie können den Sortiermodus angeben, indem Sie das Attribut ordering_mode entweder auf strict (strikter Sortiermodus, Standard) oder partial (partieller Sortiermodus) festlegen. Mit der Einstellung partial können Sie Ihre Abfragen effizienter gestalten.

Der Teilsortiermodus unterscheidet sich vom strikten Sortiermodus. Im strikten Sortiermodus werden alle Zeilen in einer bestimmten Reihenfolge angeordnet. Durch diese Gesamtsortierung funktionieren BigQuery DataFrames besser mit Pandas. Sie können mit der Eigenschaft DataFrame.iloc auf Zeilen in ihrer Reihenfolge zugreifen. Aufgrund der Gesamtsortierung und des standardmäßigen sequenziellen Index wird die Menge der gescannten Daten jedoch nicht durch Filter für Spalten oder Zeilen reduziert. Diese Verhinderung erfolgt, sofern Sie diese Filter nicht als Parameter auf die Funktionen read_gbq und read_gbq_table anwenden. Um alle Zeilen im DataFrame zu sortieren, wird in BigQuery DataFrames ein Hash aller Zeilen erstellt. Dieser Vorgang kann zu einem vollständigen Datenscan führen, bei dem Zeilen- und Spaltenfilter ignoriert werden.

Im Teilsortiermodus wird verhindert, dass BigQuery DataFrames eine Gesamtsortierung für alle Zeilen erstellt. Außerdem werden Funktionen deaktiviert, die eine Gesamtsortierung erfordern, z. B. das Attribut DataFrame.iloc. Im Teilsortiermodus wird die Klasse DefaultIndexKind ebenfalls auf einen Nullindex anstelle eines sequenziellen Index gesetzt.

Wenn Sie ein DataFrame-Objekt im Teilsortiermodus filtern, berechnet BigQuery DataFrames nicht, welche Zeilen im sequenziellen Index fehlen. Im Teilsortiermodus werden Daten auch nicht automatisch anhand des Index kombiniert. Diese Ansätze können die Effizienz Ihrer Abfragen erhöhen. Unabhängig davon, ob Sie den standardmäßigen strikten Sortiermodus oder den Teilsortiermodus verwenden, funktioniert die BigQuery DataFrames API wie die vertraute pandas API.

Sowohl beim Teil- als auch beim strengen Sortiermodus zahlen Sie für die von Ihnen verwendeten BigQuery-Ressourcen. Bei der Arbeit mit großen geclusterten und partitionierten Tabellen können Sie jedoch Kosten sparen, wenn Sie den Teilsortiermodus verwenden. Diese Kostensenkung ergibt sich, weil Zeilenfilter für Cluster- und Partitionsspalten die Menge der verarbeiteten Daten reduzieren.

Modus für Teilbestellungen aktivieren

Wenn Sie die Teilsortierung verwenden möchten, setzen Sie das Attribut ordering_mode auf partial, bevor Sie andere Vorgänge mit BigQuery DataFrames ausführen, wie im folgenden Codebeispiel gezeigt:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

Der Teilsortiermodus verhindert implizite Joins von nicht zusammenhängenden BigQuery-DataFrames-Objekten, da kein sequenzieller Index vorhanden ist. Stattdessen müssen Sie die Methode DataFrame.merge explizit aufrufen, um zwei BigQuery DataFrames-Objekte zusammenzuführen, die von verschiedenen Tabellenausdrücken abgeleitet sind.

Die Funktionen Series.unique() und Series.drop_duplicates() sind mit dem Teilsortiermodus nicht kompatibel. Verwenden Sie stattdessen die Methode groupby, um eindeutige Werte zu finden, wie im folgenden Beispiel gezeigt:

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

Im Teilsortiermodus ist die Ausgabe der Funktionen DataFrame.head(n) und Series.head(n) möglicherweise nicht bei jeder Ausführung gleich. Wenn Sie eine kleine, zufällige Stichprobe der Daten herunterladen möchten, verwenden Sie die Methode DataFrame.peek() oder Series.peek().

Eine detaillierte Anleitung zur Verwendung des Attributs ordering_mode = "partial" finden Sie unter Paketdownloads von PyPI mit BigQuery DataFrames analysieren.

Fehlerbehebung

Da BigQuery DataFrames im Teilsortiermodus manchmal keine Sortierung oder keinen Index hat, können bei der Verwendung einiger pandas-kompatibler Methoden die folgenden Probleme auftreten.

Fehler: Sortierung erforderlich

Einige Features, wie die Funktionen DataFrame.head() und DataFrame.iloc, erfordern eine Sortierung. Eine Liste der Funktionen, für die eine Sortierung erforderlich ist, finden Sie in der Spalte Sortierung erforderlich unter Unterstützte pandas APIs.

Wenn ein Objekt keine Sortierung hat, schlägt der Vorgang mit einer OrderRequiredError-Meldung wie der folgenden fehl: OrderRequiredError: Op iloc requires an ordering. Use .sort_values or .sort_index to provide an ordering.

Wie in der Fehlermeldung angegeben, können Sie mit der Methode DataFrame.sort_values() eine Sortierung nach einer oder mehreren Spalten angeben. Andere Methoden wie DataFrame.groupby() bieten implizit eine Gesamtreihenfolge basierend auf den Gruppierungsschlüsseln.

Im Gegensatz zu Pandas kann die Ausführung desselben Codes im Modus für partielle Sortierung jedes Mal zu unterschiedlichen Ergebnissen führen. Verwenden Sie eine stabile Gesamtsortierung für alle Zeilen, um konsistente Ergebnisse zu erzielen.

Null-Index-Fehler

Für einige Funktionen, z. B. die Eigenschaften DataFrame.unstack() und Series.interpolate(), ist ein Index erforderlich. Eine Liste der Funktionen, für die ein Index erforderlich ist, finden Sie in der Spalte Index erforderlich unter Unterstützte pandas APIs.

Wenn Sie einen Vorgang verwenden, für den ein Index mit dem Teilsortiermodus erforderlich ist, wird eine NullIndexError-Nachricht wie die folgende ausgegeben: NullIndexError: DataFrame cannot perform interpolate as it has no index. Set an index using set_index.

Wie in der Fehlermeldung angegeben, können Sie mit der Methode DataFrame.set_index() einen Index angeben, um nach einer oder mehreren Spalten zu sortieren. Andere Methoden wie DataFrame.groupby() stellen implizit einen Index basierend auf den Gruppierungsschlüsseln bereit, sofern der Parameter as_index=False nicht festgelegt ist.

Ergebnisse nach aufwendigen Vorgängen im Cache speichern

BigQuery DataFrames speichert Vorgänge lokal und verschiebt die Ausführung von Abfragen, bis bestimmte Bedingungen erfüllt sind. Dies kann dazu führen, dass dieselben Vorgänge mehrmals in verschiedenen Abfragen ausgeführt werden.

Wenn Sie kostspielige Vorgänge nicht wiederholen möchten, speichern Sie Zwischenergebnisse mit der Methode cache(), wie im folgenden Beispiel gezeigt:

# 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))

Bei dieser Methode wird eine temporäre BigQuery-Tabelle erstellt, in der Ihre Ergebnisse gespeichert werden. Für die Speicherung dieser temporären Tabelle in BigQuery fallen Kosten an.

Vorschau der Daten mit der Methode peek() ansehen

BigQuery DataFrames bietet zwei API-Methoden für die Vorschau von Daten:

  • peek(n) gibt n Datenzeilen zurück, wobei n die Anzahl der Zeilen ist.
  • head(n) gibt je nach Kontext die ersten n Datenzeilen zurück, wobei n die Anzahl der Zeilen ist.

Verwenden Sie die Methode head() nur, wenn die Reihenfolge der Daten wichtig ist, z. B. wenn Sie die fünf größten Werte in einer Spalte abrufen möchten. In anderen Fällen können Sie die Methode peek() verwenden, um Daten effizienter abzurufen, wie im folgenden Codebeispiel gezeigt:

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)

Sie können auch die Methode peek() verwenden, um eine kleine, zufällige Stichprobe von Daten herunterzuladen, während Sie den Modus für die partielle Sortierung verwenden.

Abruf von repr()-Daten verschieben

Sie können die Methode repr() in BigQuery DataFrames mit Notebooks oder dem Debugger Ihrer IDE aufrufen. Dadurch wird der head()-Aufruf ausgelöst, mit dem die tatsächlichen Daten abgerufen werden. Dieser Abruf kann den iterativen Codierungs- und Debugging-Prozess verlangsamen und auch Kosten verursachen.

Wenn Sie verhindern möchten, dass die Methode repr() Daten abruft, setzen Sie das Attribut repr_mode auf "deferred", wie im folgenden Beispiel gezeigt:

import bigframes.pandas as bpd

bpd.options.display.repr_mode = "deferred"

Im verzögerten Modus können Sie sich nur mit expliziten peek()- und head()-Aufrufen eine Vorschau Ihrer Daten ansehen.

Nächste Schritte