pandas on Snowflake¶
Mit pandas on Snowflake können Sie Ihren Pandas-Code direkt für Ihre Daten in Snowflake ausführen. Durch eine Änderung der Importanweisung und von ein paar Zeilen Code erhalten Sie die vertraute pandas-Erfahrung, um robuste Pipelines zu entwickeln, und profitieren gleichzeitig von der Leistung und Skalierbarkeit von Snowflake bei der Skalierung Ihrer Pipelines.
pandas on Snowflake bestimmt intelligent, ob der pandas-Code lokal ausgeführt werden soll oder die Snowflake-Engine verwendet wird, um die Leistung durch hybride Ausführung zu skalieren und zu verbessern. Bei der Arbeit mit großen Datensets in Snowflake, führt Snowpark pandas Workloads nativ in Snowflake durch Transpilierung nach SQL aus und kann so die Vorteile der Parallelisierung und der Data Governance und Sicherheit von Snowflake nutzen.
pandas on Snowflake wird über die Snowpark pandas APIals Teil der Snowpark-Bibliothek für Python bereitgestellt, die eine skalierbare Datenverarbeitung von Python-Code innerhalb der Snowflake-Plattform ermöglicht.
Vorteile der Verwendung von pandas on Snowflake¶
Trifft Python-Entwickler dort, wo sie sind – pandas on Snowflake bietet Python-Entwicklern eine vertraute Schnittstelle, indem sie eine pandas-kompatible Schicht bereitstellt, die nativ in Snowflake ausgeführt werden kann.
Skalierbares verteiltes pandas – pandas on Snowflake verbindet die praktischen Vorteile von pandas mit der Skalierbarkeitvon Snowflake, indem vorhandene Abfrageoptimierungstechniken von Snowflake genutzt werden. Es sind nur minimale Änderungen am Code erforderlich, was die Migration vereinfacht, so dass Sie nahtlos vom Prototyp zur Produktion übergehen können.
Keine zusätzliche Compute-Infrastruktur, die verwaltet und optimiert werden muss – pandas on Snowflake nutzt die leistungsstarke Compute-Engine von Snowflake, so dass Sie keine zusätzliche Compute-Infrastruktur einrichten oder verwalten müssen.
Erste Schritte mit pandas on Snowflake¶
Bemerkung
Ein praktisches Beispiel für die Verwendung von pandas on Snowflake finden Sie in diesem Notebook. Sehen Sie sich auf dieses Video an.
Um pandas on Snowflake zu installieren, können Sie conda oder pip verwenden, um das Paket zu installieren. Ausführliche Anweisungen finden Sie unter Installation.
pip install "snowflake-snowpark-python[modin]"
Sobald pandas on Snowflake installiert ist, verwenden Sie statt des Imports von pandas als import pandas as pd die folgenden beiden Zeilen:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
Hier sehen Sie ein Beispiel, wie Sie pandas on Snowflake über die pandas auf der Snowpark Python-Bibliothek mit Modin verwenden können.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
# Create a Snowpark session with a default connection.
from snowflake.snowpark.session import Session
session = Session.builder.create()
# Create a Snowpark pandas DataFrame from existing Snowflake table
df = pd.read_snowflake('SNOWFALL')
# Inspect the DataFrame
df
DAY LOCATION SNOWFALL
0 1 Big Bear 8.0
1 2 Big Bear 10.0
2 3 Big Bear NaN
3 1 Tahoe 3.0
4 2 Tahoe NaN
5 3 Tahoe 13.0
6 1 Whistler NaN
7 Friday Whistler 40.0
8 3 Whistler 25.0
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2
# Inspect the columns after update.
# Note how the data type is updated automatically after transformation.
df["DAY"]
0 1
1 2
2 3
3 1
4 2
5 3
6 1
7 2
8 3
Name: DAY, dtype: int64
# Drop rows with null values.
df.dropna()
DAY LOCATION SNOWFALL
0 1 Big Bear 8.0
1 2 Big Bear 10.0
3 1 Tahoe 3.0
5 3 Tahoe 13.0
7 2 Whistler 40.0
8 3 Whistler 25.0
# Compute the average daily snowfall across locations.
df.groupby("LOCATION").mean()["SNOWFALL"]
LOCATION
Big Bear 9.0
Tahoe 8.0
Whistler 32.5
Name: SNOWFALL, dtype: float64
read_snowflake unterstützt das Lesen von Snowflake-Ansichten, dynamischen Tabellen, Iceberg-Tabellen und mehr. Sie können eine SQL-Abfrage auch direkt übergeben und einen pandas on Snowflake-DataFrame erhalten, sodass Sie nahtlos zwischen SQL und pandas on Snowflake wechseln können.
summary_df = pd.read_snowflake("SELECT LOCATION, AVG(SNOWFALL) AS avg_snowfall FROM SNOWFALL GROUP BY LOCATION")
summary_df
Funktionsweise der hybriden Ausführung¶
Bemerkung
Ab Snowpark Python Version 1.40.0 ist die Hybridausführung standardmäßig aktiviert, wenn Sie pandas on Snowflake verwenden.
pandas on Snowflake verwendet die hybride Ausführung, um zu bestimmen, ob der pandas-Code lokal ausgeführt werden soll oder die Snowflake-Engine zur Skalierung und Verbesserung der Leistung verwendet wird. So können Sie weiterhin vertrauten pandas-Code schreiben, um robuste Pipelines zu entwickeln, ohne sich Gedanken über die optimalste und effizienteste Art und Weise machen zu müssen, Ihren Code auszuführen, während Sie gleichzeitig von der Leistung und Skalierbarkeit von Snowflake profitieren, wenn Ihre Pipelines skaliert werden.
Beispiel 1 Erstellen Sie ein kleines, 11-Zeilen-DataFrame inline. Bei der Hybridausführung wählt Snowflake das lokale, speicherinterne pandas-Backend für die Ausführung des Vorgangs aus:
# Create a basic dataframe with 11 rows
df = pd.DataFrame([
("New Year's Day", "2025-01-01"),
("Martin Luther King Jr. Day", "2025-01-20"),
("Presidents' Day", "2025-02-17"),
("Memorial Day", "2025-05-26"),
("Juneteenth National Independence Day", "2025-06-19"),
("Independence Day", "2025-07-04"),
("Labor Day", "2025-09-01"),
("Columbus Day", "2025-10-13"),
("Veterans Day", "2025-11-11"),
("Thanksgiving Day", "2025-11-27"),
("Christmas Day", "2025-12-25")
], columns=["Holiday", "Date"])
# Print out the backend used for this dataframe
df.get_backend()
# >> Output: 'Pandas'
Beispiel 2 Startwert für eine Tabelle mit 10 Millionen Zeilen von Transaktionen
# Create a 10M row table in Snowflake and populate with sythentic data
session.sql('''CREATE OR REPLACE TABLE revenue_transactions (Transaction_ID STRING, Date DATE, Revenue FLOAT);''').collect()
session.sql('''SET num_days = (SELECT DATEDIFF(DAY, '2024-01-01', CURRENT_DATE));''').collect()
session.sql('''INSERT INTO revenue_transactions (Transaction_ID, Date, Revenue) SELECT UUID_STRING() AS Transaction_ID, DATEADD(DAY, UNIFORM(0, $num_days, RANDOM()), '2024-01-01') AS Date, UNIFORM(10, 1000, RANDOM()) AS Revenue FROM TABLE(GENERATOR(ROWCOUNT => 10000000));''').collect()
# Read Snowflake table as Snowpark pandas dataframe
df_transactions = pd.read_snowflake("REVENUE_TRANSACTIONS")
Sie sehen, dass die Tabelle Snowflake als Backend nutzt, da es sich um eine große Tabelle handelt, die sich in Snowflake befindet.
print(f"The dataset size is {len(df_transactions)} and the data is located in {df_transactions.get_backend()}.")
# >> Output: The dataset size is 10000000 and the data is located in Snowflake.
#Perform some operations on 10M rows with Snowflake
df_transactions["DATE"] = pd.to_datetime(df_transactions["DATE"])
df_transactions.groupby("DATE").sum()["REVENUE"]
Beispiel 3: Daten filtern und eine groupby-Aggregation ausführen, die zu 7 Datenzeilen führt.
Wenn Daten gefiltert werden, erkennt Snowflake implizit die Auswahl des Backends von Engine-Änderungen von Snowflake zu pandas, da die Ausgabe nur 7 Datenzeilen umfasst.
# Filter to data in last 7 days
df_transactions_filter1 = df_transactions[(df_transactions["DATE"] >= pd.Timestamp.today().date() - pd.Timedelta('7 days')) & (df_transactions["DATE"] < pd.Timestamp.today().date())]
# Since filter is not yet evaluated, data stays in Snowflake
assert df_transactions_filter1.get_backend() == "Snowflake"
# After groupby operation, result is transfered from Snowflake to Pandas
df_transactions_filter1.groupby("DATE").sum()["REVENUE"]
Hinweise und Beschränkungen¶
Der DataFrame-Typ ist immer
modin.pandas.DataFrame/Series/etc, auch wenn sich das Backend ändert, um die Interoperabilität/Kompatibilität mit nachgelagertem Code sicherzustellen.Um zu bestimmen, welches Backend verwendet werden soll, verwendet Snowflake manchmal eine Schätzung der Zeilengröße, anstatt die genaue Länge des DataFrame bei jedem Schritt zu berechnen. Das bedeutet, dass Snowflake nicht immer sofort nach einem Vorgang zum optimalen Backend wechselt, wenn das Datenset größer/kleiner wird (z. B. Filtern, Aggregation).
Wenn bei einem Vorgang zwei oder mehr DataFrames über verschiedene Backends hinweg kombiniert werden, bestimmt Snowflake auf der Grundlage der niedrigsten Datenübertragungskosten, wohin die Daten verschoben werden sollen.
Filtervorgänge führen möglicherweise nicht zu einer Bewegung von Daten, da Snowflake möglicherweise nicht in der Lage ist, die Größe der zugrundeliegenden gefilterten Daten zu schätzen.
DataFrames, die aus speicherinternen Python-Daten bestehen, verwenden das pandas-Backend, wie z. B.:
pd.DataFrame([1])
pd.DataFrame(pandas.DataFrame([1]))
pd.Series({'a': [4]})
An empty DataFrame: pd.DataFrame()
DataFrames werden bei einer begrenzten Anzahl von Vorgängen automatisch von der Snowflake-Engine zur pandas-Engine verschoben. Zu diesen Vorgängen gehören
df.apply,df.plot,df.iterrows,df.itertuples,series.items, und bei Reduzierungsvorgängen, bei denen die Datenmenge garantiert kleiner ist. Nicht alle Vorgänge sind unterstützte Punkte, an denen eine Datenmigration erfolgen kann.Die Hybridausführung verschiebt einen DataFrame nicht automatisch von der pandas-Engine zurück zu Snowflake, außer in Fällen, in denen ein Vorgang wie
pd.concatauf mehrere DataFrames Auswirkungen hat.Snowflake verschiebt einen DataFrame nicht automatisch von der pandas-Engine zurück zu Snowflake, es sei denn, ein Vorgang wie
pd.concathat Auswirkungen auf DataFrames.
Wann sollte ich pandas on Snowflake verwenden?¶
Sie sollten pandas on Snowflake verwenden, wenn einer der folgenden Punkte zutrifft:
Sie sind mit den pandas-API und dem breiteren PyData-Ökosystem vertraut
Sie arbeiten in einem Team mit anderen, die mit pandas vertraut sind und an der gleichen Codebasis zusammenarbeiten möchten
Sie haben vorhandenen Code, der in Pandas geschrieben ist
Sie bevorzugen die genauere Code-Vervollständigung von AI-basierten Copilot-Tools
Weitere Informationen dazu finden Sie unter Snowpark DataFrames vs Snowpark pandas DataFrame: Was sollte ich wählen?
Verwendung von pandas on Snowflake mit Snowpark DataFrames¶
Die pandas on Snowflake und DataFrame API sind in hohem Maße interoperabel, so dass Sie eine Pipeline erstellen können, die beide APIs nutzt. Weitere Informationen dazu finden Sie unter Snowpark DataFrames vs Snowpark pandas DataFrame: Was sollte ich wählen?
Sie können die folgenden Operationen verwenden, um Konvertierungen zwischen Snowpark-DataFrames und Snowpark pandas-DataFrames durchzuführen:
Operation |
Eingabe |
Ausgabe |
|---|---|---|
Snowpark DataFrame |
Snowpark pandas-DataFrame |
|
Snowpark pandas-DataFrame oder Snowpark pandas Series |
Snowpark DataFrame |
Vergleich von pandas on Snowflake mit nativen Pandas¶
pandas on Snowflake und natives pandas haben ähnliche DataFrame-APIs mit übereinstimmenden Signaturen und ähnlicher Semantik. pandas on Snowflake bietet die gleiche API-Signatur wie natives pandas und bietet skalierbare Berechnungen mit Snowflake. pandas on Snowflake respektiert die in der Dokumentation zum nativen pandas beschriebene Semantik so weit wie möglich, verwendet aber das Verarbeitungs- und Typensystem von Snowflake. Wenn natives pandas jedoch auf einem Clientcomputer ausgeführt wird, verwendet es das Verarbeitungs- und Typensystem von Python. Informationen über die Typzuordnung zwischen pandas on Snowflake und Snowflake finden Sie unter Datentypen.
Ab Snowpark Python 1.40.0 wird pandas on Snowflake am besten mit Daten verwendet, die bereits in Snowflake vorhanden sind. Sie können die folgenden Vorgänge verwenden, um zwischen nativen pandas und pandas on Snowflake zu konvertieren:
Operation |
Eingabe |
Ausgabe |
|---|---|---|
Snowpark pandas-DataFrame |
Nativer pandas-DataFrame: Materialisiert alle Daten in der lokalen Umgebung. Wenn das Datenset sehr groß ist, kann dies zu einem Fehler wegen unzureichendem Arbeitsspeicher führen. |
|
Native pandas DataFrame, Rohdaten, Snowpark pandas-Objekt |
Snowpark pandas-DataFrame |
Ausführungsumgebung¶
pandas: Arbeitet auf einem einzigen Computer und verarbeitet Daten im Arbeitsspeicher.pandas on Snowflake: Integriert in Snowflake, das verteiltes Computing über einen Cluster von Rechnern für große Datensets ermöglicht, während pandas im Arbeitsspeicher für die Verarbeitung kleiner Datensets genutzt wird. Diese Integration ermöglicht die Verarbeitung viel größerer Datensets, die die Kapazität des Arbeitsspeichers eines einzelnen Rechners übersteigen würden. Beachten Sie, dass die Verwendung der Snowpark pandas-API eine Verbindung zu Snowflake erfordert.
Lazy- vs. Eager-Evaluation¶
pandas: Führt Operationen sofort aus und materialisiert die Ergebnisse nach jeder Operation vollständig im Arbeitsspeicher. Diese Eeager-Evaluation von Operationen kann zu einem erhöhten Arbeitsspeicherdruck führen, da Daten innerhalb eines Computers umfangreich verschoben werden müssen.pandas on Snowflake: Bietet die gleiche API-Erfahrung wie pandas. Es ahmt das Eager-Evaluationsmodell von pandas nach, baut aber intern einen Lazy-evaluierten Abfragegraphen auf, um eine Optimierung über alle Operationen hinweg zu ermöglichen.Das Zusammenführen und Transpilieren von Operationen über einen Abfragegraphen ermöglicht zusätzliche Optimierungsmöglichkeiten für die zugrunde liegende verteilte Snowflake-Computing-Engine, was sowohl die Kosten als auch die Laufzeit der End-to-End-Pipeline im Vergleich zur direkten Ausführung von pandas in Snowflake verringert.
Bemerkung
Für E/A-bezogene APIs sowie APIs, deren Rückgabewert kein Snowpark pandas-Objekt ist (d. h.
DataFrame,SeriesoderIndex), erfolgt immer eine Eager-Evaluation. Beispiel:read_snowflaketo_snowflaketo_pandasto_dictto_list__repr__Die Dunder-Methode
__array__, die von einigen Drittanbieter-Bibliotheken wie scikit-learn automatisch aufgerufen werden kann. Aufrufe dieser Methode materialisieren die Ergebnisse auf dem lokalen Computer.
Datenquelle und Datenspeicher¶
pandas: Unterstützt die verschiedenen Reader und Writer, die in der pandas-Dokumentation unter IO Tools (text, CSV, HDF5 …) aufgeführt sind.pandas on Snowflake: Kann aus Snowflake-Tabellen lesen und schreiben und lokale oder im Stagingbereich befindliche CSV-, JSON- oder Parquet-Dateien lesen. Weitere Informationen dazu finden Sie unter IO (Lesen und Schreiben).
Datentypen¶
pandas: Bietet eine Vielzahl von Datentypen, wie z. B. Ganzzahlen, Fließkommazahlen, Zeichenfolgen,datetime-Typen und kategorische Typen. Es unterstützt auch benutzerdefinierte Datentypen. Datentypen in pandas werden in der Regel von den zugrunde liegenden Daten abgeleitet und streng erzwungen.pandas on Snowflake: Ist durch das Snowflake-Typensystembegrenzt, das pandas-Objekte SQL zuordnet, indem es die pandas-Datentypen in die SQL-Typen von Snowflake übersetzt. Die meisten pandas-Typen haben eine natürliche Entsprechung in Snowflake, aber die Zuordnung ist nicht immer eins zu eins. In einigen Fällen werden mehrere pandas-Typen demselben SQL-Typ zugeordnet.
In der folgenden Tabelle sind die Typzuordnungen zwischen pandas und Snowflake SQL aufgeführt:
pandas-Typ |
Snowflake-Typ |
|---|---|
Alle Integer-Typen mit und ohne Vorzeichen, einschließlich der erweiterten Integer-Typen von pandas |
NUMBER(38, 0) |
Alle Float-Typen, einschließlich der erweiterten Float-Datentypen von pandas |
FLOAT |
|
BOOLEAN |
|
STRING |
|
TIME |
|
DATE |
Alle Zeitzonen-unabhängigen |
TIMESTAMP_NTZ |
Alle Zeitzonen-kompatiblen |
TIMESTAMP_TZ |
|
ARRAY |
|
MAP |
Objektspalte mit gemischten Datentypen |
VARIANT |
Timedelta64[ns] |
NUMBER(38, 0) |
Bemerkung
Kategoriale, Perioden-, Intervall-, Sparse- und benutzerdefinierte Datentypen werden nicht unterstützt. Timedelta wird derzeit nur auf dem pandas on Snowpark-Client unterstützt. Wenn Sie Timedelta zurück nach Snowflake schreiben, wird es als Zahlentyp gespeichert.
Die folgende Tabelle enthält die Zuordnung von Snowflake SQL-Typen zurück zu pandas on Snowflake-Typen unter Verwendung von df.dtypes:
Snowflake-Typ |
pandas on Snowflake-Typ ( |
|---|---|
NUMBER ( |
|
NUMBER ( |
|
BOOLEAN |
|
STRING, TEXT |
|
VARIANT, BINARY, GEOMETRY, GEOGRAPHY |
|
ARRAY |
|
OBJECT |
|
TIME |
|
TIMESTAMP, TIMESTAMP_NTZ, TIMESTAMP_LTZ, TIMESTAMP_TZ |
|
DATE |
|
Bei der Konvertierung von Snowpark pandas DataFrame in native pandas DataFrame mit to_pandas() haben die nativen pandas DataFrame verfeinerte Datentypen im Vergleich zu den pandas on Snowflake-Typen, die mit Zuordnung von Datentypen zwischen SQL und Python für Funktionen und Prozeduren kompatibel sind.
Umwandlung und Typ-Inferenz¶
pandas: Verlässt sich auf NumPy und folgt standardmäßig dem NumPy- und dem Python-Typsystem für implizite Typumwandlung und Typinferenz. Beispielsweise werden Boolesche Werte als Integer-Typen behandelt, sodass1 + Trueden Wert2zurückgibt.pandas on Snowflake: Ordnet NumPy und Python-Typen den Snowflake-Typen gemäß der obigen Tabelle zu und verwendet das zugrunde liegende Snowflake-Typsystem für implizite Typumwandlung und Typinferenz. Beispielsweise werden gemäß der Logische Datentypen Boolean-Typen nicht implizit in Integer-Typen konvertiert, sodass1 + Truezu einem Typkonvertierungsfehler führt.
Behandlung von Nullwerten¶
pandas: In den pandas-Versionen 1.x war pandas flexibel bei der Behandlung fehlender Daten, sodass es alle PythonNone,np.nan,pd.NaN,pd.NAundpd.NaTals fehlende Werte behandelte. In späteren Versionen von pandas (2.2.x) werden diese Werte als unterschiedliche Werte behandelt.pandas on Snowflake: Verwendet einen ähnlichen Ansatz wie frühere pandas-Versionen, bei dem alle oben aufgeführten Werte als fehlende Werte behandelt werden. Snowpark verwendet wiederNaN,NAundNaTvon pandas. Beachten Sie jedoch, dass alle diese fehlenden Werte austauschbar behandelt und als SQL NULL in der Snowflake-Tabelle gespeichert werden.
Offset-/Frequenz-Aliasse¶
pandas: Datumsoffsets in pandas wurden in Version 2.2.1 geändert. Aliasse mit einem Buchstaben'M','Q','Y'und andere wurden zugunsten von Offsets mit zwei Buchstaben veraltet.pandas on Snowflake: Verwendet ausschließlich die neuen Offsets, die in der pandas-Dokumentation zu Zeitreihen beschrieben sind.
Installation¶
Voraussetzungen
Die folgenden Paketversionen sind erforderlich:
Python 3.9 (veraltet), 3.10, 3.11, 3.12 oder 3.13
modin Version 0.32.0
pandas Version 2.2.*
Tipp
Um pandas on Snowflake in Snowflake Notebooks zu verwenden, lesen Sie die Anweisungen zur Einrichtung unter pandas on Snowflake in Notebooks.
Um pandas on Snowflake in Ihrer Entwicklungsumgebung zu installieren, gehen Sie folgendermaßen vor:
Wechseln Sie in Ihr Projektverzeichnis, und aktivieren Sie Ihre virtuelle Python-Umgebung:
Bemerkung
Die API befindet sich in aktiver Entwicklung, daher empfehlen wir, sie in einer virtuellen Python-Umgebung zu installieren und nicht systemweit. Auf diese Weise kann jedes Projekt, das Sie erstellen, eine bestimmte Version verwenden, sodass Sie von Änderungen in zukünftigen Versionen unberührt bleiben.
Sie können eine virtuelle Python-Umgebung für eine bestimmte Python-Version mit Tools wie Anaconda, Miniconda oder virtualenv erstellen.
Um zum Beispiel mit conda eine virtuelle Umgebung für Python 3.12 zu erstellen, geben Sie Folgendes ein:
conda create --name snowpark_pandas python=3.12 conda activate snowpark_pandas
Bemerkung
Wenn Sie zuvor eine ältere Version von pandas on Snowflake mit Python 3.9 und pandas 1.5.3 installiert haben, müssen Sie Ihre Python- und pandas-Versionen wie oben beschrieben aktualisieren. Führen Sie die Schritte zum Erstellen einer neuen Umgebung mit Python 3.10 oder 3.13 aus.
Installieren Sie die Snowpark Python-Bibliothek mit Modin.
pip install "snowflake-snowpark-python[modin]"
oder
conda install snowflake-snowpark-python modin==0.28.1
Bemerkung
Stellen Sie sicher, dass
snowflake-snowpark-pythonVersion 1.17.0 oder höher installiert ist.
Authentifizierung mit Snowflake¶
Bevor Sie pandas on Snowflake verwenden, müssen Sie eine Sitzung mit der Snowflake-Datenbank einrichten. Sie können eine Konfigurationsdatei verwenden, um die Verbindungsparameter für Ihre Sitzung auszuwählen, oder Sie können sie in Ihrem Code spezifizieren. Weitere Informationen dazu finden Sie unter Erstellen einer Sitzung für Snowpark Python. Wenn eine eindeutige aktive Snowpark Python-Sitzung existiert, werden pandas on Snowflake diese automatisch verwenden. Beispiel:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
CONNECTION_PARAMETERS = {
'account': '<myaccount>',
'user': '<myuser>',
'password': '<mypassword>',
'role': '<myrole>',
'database': '<mydatabase>',
'schema': '<myschema>',
'warehouse': '<mywarehouse>',
}
session = Session.builder.configs(CONNECTION_PARAMETERS).create()
# pandas on Snowflake will automatically pick up the Snowpark session created above.
# It will use that session to create new DataFrames.
df = pd.DataFrame([1, 2])
df2 = pd.read_snowflake('CUSTOMER')
pd.session ist eine Snowpark-Sitzung, d. h. Sie können mit ihr alles tun, was Sie auch mit jeder anderen Snowpark-Sitzung tun können. Sie können damit zum Beispiel eine beliebige SQL-Abfrage ausführen, die zu einem Snowpark-DataFrame gemäß Sitzungs-API führt. Beachten Sie aber, dass das Ergebnis ein Snowpark-DataFrame und kein Snowpark pandas-DataFrame sein wird.
# pd.session is the session that pandas on Snowflake is using for new DataFrames.
# In this case it is the same as the Snowpark session that we've created.
assert pd.session is session
# Run SQL query with returned result as Snowpark DataFrame
snowpark_df = pd.session.sql('select * from customer')
snowpark_df.show()
Alternativ können Sie Ihre Snowpark-Verbindungsparameter in einer Konfigurationsdatei konfigurieren. Damit entfällt die Notwendigkeit, Verbindungsparameter in Ihrem Code zu spezifizieren, sodass Sie Ihren pandas on Snowflake-Code fast so schreiben können, wie Sie normalerweise pandas-Code schreiben würden. Um dies zu erreichen, erstellen Sie eine Konfigurationsdatei unter ~/.snowflake/connections.toml, die in etwa so aussieht:
default_connection_name = "default"
[default]
account = "<myaccount>"
user = "<myuser>"
password = "<mypassword>"
role="<myrole>"
database = "<mydatabase>"
schema = "<myschema>"
warehouse = "<mywarehouse>"
Im Code müssen Sie dann nur noch snowflake.snowpark.Session.builder.create() verwenden, um eine Sitzung mit diesen Anmeldeinformationen zu erstellen.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
# Session.builder.create() will create a default Snowflake connection.
Session.builder.create()
# create a DataFrame.
df = pd.DataFrame([[1, 2], [3, 4]])
Sie können auch mehrere Snowpark-Sitzungen erstellen und dann eine davon den pandas on Snowflake zuweisen. pandas on Snowflake verwendet nur eine Sitzung, daher müssen Sie eine der Sitzungen explizit den pandas on Snowflake mit pd.session = pandas_session zuweisen.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
pandas_session = Session.builder.configs({"user": "<user>", "password": "<password>", "account": "<account1>").create()
other_session = Session.builder.configs({"user": "<user>", "password": "<password>", "account": "<account2>").create()
pd.session = pandas_session
df = pd.DataFrame([1, 2, 3])
Das folgende Beispiel zeigt, dass der Versuch, pandas on Snowflake zu verwenden, wenn es keine aktive Snowpark-Sitzung gibt, eine SnowparkSessionException mit einem Fehler wie „pandas on Snowflake requires an active snowpark session, but there is none“ auslöst. Sobald Sie eine Sitzung erstellt haben, können Sie pandas on Snowflake nutzen. Beispiel:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
df = pd.DataFrame([1, 2, 3])
Das folgende Beispiel zeigt, dass der Versuch, pandas on Snowflake zu verwenden, wenn es mehrere aktive Snowpark-Sitzungen gibt, eine SnowparkSessionException mit einer Meldung wie „There are multiple active snowpark sessions, but you need to choose one for pandas on Snowflake“ auslöst.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
pandas_session = Session.builder.configs({"user": "<user>", "password": "<password>", "account": "<account1>"}).create()
other_session = Session.builder.configs({"user": "<user>", "password": "<password>", "account": "<account2>"}).create()
df = pd.DataFrame([1, 2, 3])
Bemerkung
Sie müssen die Sitzung festlegen, die für einen neuen pandas on Snowflake-DataFrame oder eine Series über modin.pandas.session verwendet wird. Das Zusammenführen von DataFrames, das mit verschiedenen Sitzungen erstellt wurde, wird jedoch nicht unterstützt. Sie sollten also vermeiden, wiederholt verschiedene Sitzungen festzulegen und DataFrames mit verschiedenen Sitzungen in einem Workflow zu erstellen.
API-Referenz¶
Siehe die pandas on Snowflake API-Referenz für die vollständige Auflistung der derzeit implementierten APIs und verfügbaren Methoden.
Eine vollständige Liste der unterstützten Operationen finden Sie in den folgenden Tabellen in der pandas on Snowflake-Referenz:
APIs und Konfigurationsparameter für die Hybridausführung¶
Die Hybridausführung verwendet eine Kombination aus der Schätzung der Datenset-Größe und den Vorgängen, die auf den DataFrame angewendet werden, um die Wahl des Backends zu bestimmen. Im Allgemeinen wird bei Datensets unter 100.000 Zeilen lokales pandas verwendet. Bei mehr als 100.000 Zeilen wird in der Regel Snowflake verwendet, es sei denn, das Datenset wird aus lokalen Dateien geladen.
Konfigurieren der Transferkosten¶
Um den Standard-Schwellenwert für einen Wechsel in einen anderen Zeilengrenzwert zu ändern, können Sie die Umgebungsvariable vor dem Initialisieren eines DataFrame ändern:
# Change row transfer threshold to 500k
from modin.config.envvars import SnowflakePandasTransferThreshold
SnowflakePandasTransferThreshold.put(500_000)
Durch Einstellen dieses Wertes wird das Übertragen von Zeilen aus Snowflake bestraft.
Konfigurieren der lokalen Ausführungslimits¶
Sobald ein DataFrame lokal ist, bleibt er im Allgemeinen lokal, es sei denn, es ist notwendig, ihn für eine Zusammenführung zurück zu Snowflake zu verschieben. Es gibt jedoch eine Obergrenze für die maximale Datengröße, die lokal verarbeitet werden kann. Derzeit beträgt diese Grenze 10 Millionen Zeilen.
Prüfen und Einstellen des Backends¶
Um das aktuelle Backend Ihrer Wahl zu überprüfen, können Sie den Befehl df.getbackend() verwenden, der Pandas für die lokale Ausführung oder Snowflake für die Pushdown-Ausführung zurückgibt.
Um das aktuelle Backend Ihrer Wahl mit entweder set_backend oder seinem Alias move_to festzulegen:
df_local = df.set_backend('Pandas')
df_local = df.move_to('Pandas')
df_snow = df.set_backend('Snowflake')
Sie können das Backend auch direkt festlegen:
df.set_backend('Pandas', inplace=True)
So können Sie Informationen darüber prüfen und anzeigen, warum Daten verschoben wurden:
pd.explain_switch()
Manuelle Überschreibung der Backend-Auswahl durch Pinning des Backends¶
Standardmäßig wählt Snowflake automatisch das beste Backend für einen bestimmten DataFrame und einen Vorgang aus. Wenn Sie die automatische Auswahl der Engine überschreiben möchten, können Sie die automatische Umschaltung für ein Objekt und alle daraus erzeugten Daten mit der Methode pin_backend() deaktivieren:
pinned_df_snow = df.move_to('Snowflake').pin_backend()
Um den automatischen Backend-Wechsel wieder zu aktivieren, rufen Sie unpin_backend() auf:
unpinned_df_snow = pinned_df_snow.unpin_backend()
Snowpark pandas in Snowflake-Notebooks verwenden¶
Um pandas on Snowflake in Snowflake-Notebooks zu verwenden, siehe pandas on Snowflake in Notebooks.
Snowpark pandas in Python-Arbeitsblättern verwenden¶
Um Snowpark pandas zu verwenden, müssen Sie Modin installieren, indem Sie modin unter Packages in der Python-Arbeitsblattumgebung auswählen.
Sie können den Rückgabetyp der Python-Funktion unter Settings > Return type auswählen. Standardmäßig ist dies als Snowpark-Tabelle eingestellt. Um den Snowpark pandas-DataFrame als Ergebnis anzuzeigen, können Sie einen Snowpark pandas-DataFrame in einen Snowpark-DataFrame umwandeln, indem Sie to_snowpark() aufrufen. Bei dieser Konvertierung fallen keine E/A-Kosten an.
Hier sehen Sie ein Beispiel für die Verwendung von Snowpark pandas mit Python-Arbeitsblättern:
import snowflake.snowpark as snowpark
def main(session: snowpark.Session):
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
[1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
[1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
columns=["DAY", "LOCATION", "SNOWFALL"])
# Print a sample of the dataframe to standard output.
print(df)
snowpark_df = df.to_snowpark(index=None)
# Return value will appear in the Results tab.
return snowpark_df
Verwendung von pandas on Snowflake in gespeicherten Prozeduren¶
Sie können pandas on Snowflake in einer gespeicherten Prozedur verwenden, um eine Datenpipeline aufzubauen und die Ausführung der gespeicherten Prozedur mit Aufgaben zu planen.
Hier sehen Sie, wie Sie eine gespeicherte Prozedur mit SQL erstellen können:
CREATE OR REPLACE PROCEDURE run_data_transformation_pipeline_sp()
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = 3.12
PACKAGES = ('snowflake-snowpark-python','modin')
HANDLER='data_transformation_pipeline'
AS $$
def data_transformation_pipeline(session):
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from datetime import datetime
# Create a Snowpark pandas DataFrame with sample data.
df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
[1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
[1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
columns=["DAY", "LOCATION", "SNOWFALL"])
# Drop rows with null values.
df = df.dropna()
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2
# Save Results as a Snowflake Table
timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M")
save_path = f"OUTPUT_{timestamp}"
df.to_snowflake(name=save_path, if_exists="replace", index=False)
return f'Transformed DataFrame saved to {save_path}.'
$$;
Hier sehen Sie, wie Sie eine gespeicherte Prozedur mit Snowflake Python API erstellen können:
from snowflake.snowpark.context import get_active_session
session = get_active_session()
from snowflake.snowpark import Session
def data_transformation_pipeline(session: Session) -> str:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from datetime import datetime
# Create a Snowpark pandas DataFrame with sample data.
df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
[1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
[1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
columns=["DAY", "LOCATION", "SNOWFALL"])
# Drop rows with null values.
df = df.dropna()
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2
# Save Results as a Snowflake Table
timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M")
save_path = f"OUTPUT_{timestamp}"
df.to_snowflake(name=save_path, if_exists="replace", index=False)
return f'Transformed DataFrame saved to {save_path}.'
dt_pipeline_sproc = session.sproc.register(name="run_data_transformation_pipeline_sp",
func=data_transformation_pipeline,
replace=True,
packages=['modin', 'snowflake-snowpark-python'])
Um die gespeicherte Prozedur aufzurufen, können Sie dt_pipeline_sproc() in Python oder CALL run_data_transformation_pipeline_sp() in SQL ausführen.
Verwendung von pandas on Snowflake mit Bibliotheken von Drittanbietern¶
pandas wird häufig zusammen mit der APIs-Bibliothek von Drittanbietern für Visualisierungs- und Machine Learning-Anwendungen verwendet. pandas on Snowflake ist mit den meisten dieser Bibliotheken interoperabel, so dass sie ohne explizite Konvertierung in pandas DataFrames verwendet werden können. Beachten Sie jedoch, dass die verteilte Ausführung in den meisten Bibliotheken von Drittanbietern nicht unterstützt wird, außer in bestimmten Anwendungsfällen. Dies kann daher zu einer langsameren Leistung bei großen Datensätzen führen.
Unterstützte Bibliotheken von Drittanbietern¶
Die unten aufgeführten Bibliotheken akzeptieren pandas on Snowflake DataFrames als Eingabe, aber nicht alle ihre Methoden wurden getestet. Einen detaillierten Status der Interoperabilität auf der API-Ebene finden Sie unter Interoperabilität mit Bibliotheken von Drittanbietern.
Plotly
Altair
Seaborn
Matplotlib
Numpy
Scikit-learn
XGBoost
NLTK
Streamlit
pandas on Snowflake hat derzeit eine beschränkte Kompatibilität für bestimmte NumPy und Matplotlib APIs, wie die verteilte Implementierung für np.where und die Interoperabilität mit df.plot. Wenn Sie Snowpark pandas DataFrames über to_pandas() konvertieren, wenn Sie mit diesen Bibliotheken von Drittanbietern arbeiten, vermeiden Sie mehrere I/O-Aufrufe.
Hier ist ein Beispiel mit Altair für die Visualisierung und scikit-learn für das maschinelle Lernen.
# Create a Snowpark session with a default connection.
session = Session.builder.create()
train = pd.read_snowflake('TITANIC')
train[['Pclass', 'Parch', 'Sex', 'Survived']].head()
Pclass Parch Sex Survived
0 3 0 male 0
1 1 0 female 1
2 3 0 female 1
3 1 0 female 1
4 3 0 male 0
import altair as alt
survived_per_age_plot = alt.Chart(train).mark_bar(
).encode(
x=alt.X('Age', bin=alt.Bin(maxbins=25)),
y='count()',
column='Survived:N',
color='Survived:N',
).properties(
width=300,
height=300
).configure_axis(
grid=False
)
Sie können das Überleben auch nach Geschlecht analysieren.
# Perform groupby aggregation with Snowpark pandas
survived_per_gender = train.groupby(['Sex','Survived']).agg(count_survived=('Survived', 'count')).reset_index()
survived_per_gender_pandas = survived_per_gender
survived_per_gender_plot = alt.Chart(survived_per_gender).mark_bar().encode(
x='Survived:N',
y='Survived_Count',
color='Sex',
column='Sex'
).properties(
width=200,
height=200
).configure_axis(
grid=False
)
Sie können jetzt scikit-learn verwenden, um ein einfaches Modell zu trainieren.
feature_cols = ['Pclass', 'Parch']
X_pandas = train.loc[:, feature_cols]
y_pandas = train["Survived"]
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_pandas, y_pandas)
y_pred_pandas = logreg.predict(X_pandas)
acc_eval = accuracy_score(y_pandas, y_pred_pandas)
Bemerkung
Für eine bessere Leistung empfehlen wir die Konvertierung in pandas DataFrames über to_pandas(), insbesondere bei der Verwendung von Bibliotheken für maschinelles Lernen wie scikit-learn. Die Funktion to_pandas() sammelt jedoch alle Zeilen, so dass es möglicherweise besser ist, die Größe des Datenrahmens zunächst mit sample(frac=0.1) oder head(10) zu reduzieren.
Nicht unterstützte Bibliotheken¶
Wenn Sie nicht unterstützte Bibliotheken von Drittanbietern mit einem pandas on Snowflake DataFrame verwenden, empfehlen wir, das pandas on Snowflake DataFrame in einen pandas DataFrame zu konvertieren, indem Sie to_pandas() aufrufen, bevor Sie den DataFrame an die Methode der Drittanbieter-Bibliothek übergeben.
Bemerkung
Der Aufruf von to_pandas() zieht Ihre Daten aus Snowflake heraus und in den Speicher, daher sollten Sie dies für große Datensätze und sensible Anwendungsfälle in Betracht ziehen.
Verwendung von Snowflake Cortex LLM-Funktionen mit Snowpark Pandas¶
Sie können Snowflake Cortex LLM Funktionen über die Snowpark pandas apply-Funktion verwenden.
Sie wenden die Funktion mit speziellen Schlüsselwortargumenten an. Derzeit werden die folgenden Cortex-Funktionen unterstützt:
Das folgende Beispiel verwendet die Funktion TRANSLATE über mehrere Datensätze in einem Snowpark pandas DataFrame:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.cortex import Translate
content_df = pd.DataFrame(["good morning","hello", "goodbye"], columns=["content"])
result = content_df.apply(Translate, from_language="en", to_language="de")
result["content"]
Ausgabe:
Guten Morgen
Hallo
Auf Wiedersehen
Name: content, dtype: object
Im folgenden Beispiel wird die SENTIMENT (SNOWFLAKE.CORTEX)-Funktion für die Snowflake-Tabelle reviews verwendet:
from snowflake.cortex import Sentiment
s = pd.read_snowflake("reviews")["content"]
result = s.apply(Sentiment)
result
Das folgende Beispiel verwendet EXTRACT_ANSWER (SNOWFLAKE.CORTEX), um eine Frage zu beantworten:
from snowflake.cortex import ExtractAnswer
content = "The Snowflake company was co-founded by Thierry Cruanes, Marcin Zukowski, and Benoit Dageville in 2012 and is headquartered in Bozeman, Montana."
df = pd.DataFrame([content])
result = df.apply(ExtractAnswer, question="When was Snowflake founded?")
result[0][0][0]["answer"]
Ausgabe:
'2012'
Bemerkung
Das Paket snowflake-ml-python muss installiert sein, um die Funktionen von Cortex LLM nutzen zu können.
Einschränkungen¶
pandas on Snowflake weist folgende Beschränkungen auf:
pandas on Snowflake bietet keine Garantie für die Kompatibilität mit OSS-Bibliotheken von Drittanbietern. Ab Version 1.14.0a1 führt Snowpark pandas jedoch eine begrenzte Kompatibilität für NumPy ein, insbesondere für die Verwendung von
np.where. Weitere Informationen dazu finden Sie unter NumPy-Interoperabilität.Wenn Sie die Bibliothek eines Drittanbieters APIs mit einem Snowpark pandas DataFrame aufrufen, empfiehlt Snowflake, dass Sie das Snowpark pandas DataFrame in ein pandas DataFrame umwandeln, indem Sie
to_pandas()aufrufen, bevor Sie DataFrame an den Aufruf der Bibliothek des Drittanbieters übergeben. Weitere Informationen dazu finden Sie unter Verwendung von pandas on Snowflake mit Bibliotheken von Drittanbietern.pandas on Snowflake ist nicht in Snowpark ML integriert. Wenn Sie Snowpark ML verwenden, empfehlen wir Ihnen, das Snowpark pandas DataFrame mit to_snowpark() in ein Snowpark DataFrame zu konvertieren, bevor Sie Snowpark ML aufrufen.
Lazy-
MultiIndex-Objekte werden nicht unterstützt. WennMultiIndexverwendet wird, wird ein natives PandasMultiIndex-Objekt zurückgegeben, bei dem alle Daten von der Clientseite abgerufen werden müssen.Noch nicht alle pandas-APIs haben eine verteilte Implementierung in pandas on Snowflake. Bei nicht unterstützten APIs wird
NotImplementedErrorausgelöst. Weitere Informationen zur Unterstützung von APIs finden Sie in der API-Referenzdokumentation.pandas on Snowflake bietet Kompatibilität mit jeder Patch-Version von pandas 2.2.
Snowpark pandas kann nicht innerhalb der
apply-Funktion von Snowpark pandas referenziert werden. Sie können native Pandas nur innerhalb vonapplyverwenden.Nachfolgenden sehen Sie ein Beispiel:
import modin.pandas as pd import pandas df.apply(lambda row: pandas.to_datetime(f"{row.date} {row.time}"), axis=1)
Problembehandlung¶
Dieser Abschnitt beschreibt Tipps zur Fehlerbehebung bei der Verwendung von pandas on Snowflake.
Versuchen Sie bei der Fehlersuche, dieselbe Operation mit einem nativen Pandas DataFrame (oder einem Beispiel) auszuführen, um zu sehen, ob derselbe Fehler weiterhin auftritt. Dieser Ansatz könnte Hinweise darauf liefern, wie Sie Ihre Abfrage korrigieren können. Beispiel:
df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "z"]}) # Running this in Snowpark pandas throws an error df["A"].sum() # Convert a small sample of 10 rows to pandas DataFrame for testing pandas_df = df.head(10).to_pandas() # Run the same operation. KeyError indicates that the column reference is incorrect pandas_df["A"].sum() # Fix the column reference to get the Snowpark pandas query working df["a"].sum()
Wenn Sie ein langlaufendes Notebook geöffnet haben, beachten Sie, dass Snowflake-Sitzungen standardmäßig ein Timeout haben, wenn die Sitzung 240 Minuten (4 Stunden) inaktiv war. Wenn die Sitzung abläuft, erhalten Sie den folgenden Fehler, wenn Sie weitere Abfragen von pandas on Snowflake ausführen: „Das Token für die Authentifizierung ist abgelaufen“. The user must authenticate again.“ An diesem Punkt müssen Sie erneut die Verbindung zu Snowflake herstellen. Dies kann dazu führen, dass alle nicht persistente Sitzungsvariablen verloren gehen. Weitere Informationen zur Konfiguration des Parameters für die Leerlauf-Timeout der Sitzung finden Sie unter Session policies.
Best Practices¶
In diesem Abschnitt werden Best Practices beschrieben, die Sie bei der Verwendung von pandas on Snowflake beachten sollten.
Vermeiden Sie die Verwendung von iterativen Codemustern wie
for-Schleifen,iterrowsunditeritems. Iterative Codemuster erhöhen schnell die generierte Abfragekomplexität. Überlassen Sie pandas on Snowflake die Datenverteilung und die Parallelisierung der Berechnungen durchführen und nicht dem Clientcode. Versuchen Sie bei iterativen Mustern nach Operationen zu suchen, die auf der gesamten DataFrame durchgeführt werden können, und verwenden Sie stattdessen die entsprechenden Operationen.
for i in np.arange(0, 50):
if i % 2 == 0:
data = pd.concat([data, pd.DataFrame({'A': i, 'B': i + 1}, index=[0])], ignore_index=True)
else:
data = pd.concat([data, pd.DataFrame({'A': i}, index=[0])], ignore_index=True)
# Instead of creating one DataFrame per row and concatenating them,
# try to directly create the DataFrame out of the data, like this:
data = pd.DataFrame(
{
"A": range(0, 50),
"B": [i + 1 if i % 2 == 0 else None for i in range(50)],
},
)
Vermeiden Sie den Aufruf von
apply,applymapodertransform, die schließlich mit UDFs oder UDTFs implementiert werden und möglicherweise nicht so leistungsfähig wie reguläre SQL-Abfragen sind. Wenn die angewandte Funktion über eine gleichwertige DataFrame- oder Series-Operation verfügt, verwenden Sie stattdessen diese Operation. Verwenden Sie also anstelle vondf.groupby('col1').apply('sum')den direkten Aufrufdf.groupby('col1').sum().Rufen Sie
to_pandas()auf, bevor Sie die DataFrame oder Serie an einen Bibliotheksaufruf eines Drittanbieters übergeben. pandas on Snowflake bietet keine Kompatibilitätsgarantie mit Bibliotheken von Drittanbietern.Verwenden Sie eine materialisierte reguläre Snowflake-Tabelle, um zusätzlichen I/O-Overhead zu vermeiden. pandas on Snowflake arbeitet auf einem Daten-Snapshot, der nur für reguläre Tabellen funktioniert. Für andere Typen, einschließlich externer Tabellen, Ansichten und Apache Iceberg™-Tabellen, wird vor dem Erstellen des Snapshots eine temporäre Tabelle erstellt, was zusätzlichen Materialisierungs-Overhead verursacht.
pandas on Snowflake bietet eine schnelle und kopierfreie Klon-Funktion beim Erstellen von DataFrames aus Snowflake-Tabellen und nutzt dazu
read_snowflake.Überprüfen Sie den Ergebnistyp, bevor Sie mit anderen Operationen fortfahren, und führen Sie bei Bedarf eine explizite Typumwandlung mit
astypeaus.Aufgrund der begrenzten Fähigkeit zur Typinferenz gibt
df.applybei fehlendem Typhinweis Ergebnisse vom Typ Objekt (Variant) zurück, auch wenn das Ergebnis nur Integer-Werte enthält. Wenn andere Operationen erfordern, dassdtypeintist, können Sie eine explizite Typumwandlung ausführen, indem Sie die Methodeastypeaufrufen, um den Spaltentyp zu korrigieren, bevor Sie fortfahren.Vermeiden Sie es, APIs aufzurufen, die Evaluation und Materialisierung erfordern, wenn dies nicht notwendig ist.
APIs, die nicht
SeriesoderDataframezurückgeben, erfordern eine Eager-Evaluation und -Materialisierung, um das Ergebnis mit dem korrekten Typ zu erzeugen. Dasselbe gilt für Plot-Methoden. Reduzieren Sie die Anrufe dieser APIs, um unnötige Evaluationen und Materialisierungen zu vermeiden.Vermeiden Sie den Aufruf von
np.where(<cond>, <scalar>, n)bei großen Datensets.<scalar>wird an einen DataFrame in der Größe von<cond>gesendet, was langsam sein kann.Bei der Arbeit mit iterativ aufgebauten Abfragen kann
df.cache_resultverwendet werden, um Zwischenergebnisse zu materialisieren, um die wiederholte Auswertung zu reduzieren, die Latenzzeit zu verbessern und die Komplexität der gesamten Abfrage zu verringern. Beispiel:df = pd.read_snowflake('pandas_test') df2 = pd.pivot_table(df, index='index_col', columns='pivot_col') # expensive operation df3 = df.merge(df2) df4 = df3.where(df2 == True)
Im obigen Beispiel ist die Abfrage zum Erstellen von
df2teuer im Computing und wird sowohl beim Erstellen vondf3als auch vondf4wiederverwendet. Die Materialisierung vondf2in eine temporäre Tabelle (sodass nachfolgende Operationen mitdf2ein Tabellenscan anstelle eines Pivots sind) kann die Gesamtlatenz des Codeblocks verringern:df = pd.read_snowflake('pandas_test') df2 = pd.pivot_table(df, index='index_col', columns='pivot_col') # expensive operation df2.cache_result(inplace=True) df3 = df.merge(df2) df4 = df3.where(df2 == True)
Beispiele¶
Hier ist ein Codebeispiel mit pandas-Operationen. Wir beginnen mit einem Snowpark pandas DataFrame namens pandas_test, der drei Spalten enthält: COL_STR, COL_FLOAT und COL_INT. Das zu diesen Beispielen gehörende Notebook finden Sie unter pandas on Snowflake-Beispiele im Snowflake-Labs-Repository.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
CONNECTION_PARAMETERS = {
'account': '<myaccount>',
'user': '<myuser>',
'password': '<mypassword>',
'role': '<myrole>',
'database': '<mydatabase>',
'schema': '<myschema>',
'warehouse': '<mywarehouse>',
}
session = Session.builder.configs(CONNECTION_PARAMETERS).create()
df = pd.DataFrame([['a', 2.1, 1],['b', 4.2, 2],['c', 6.3, None]], columns=["COL_STR", "COL_FLOAT", "COL_INT"])
df
COL_STR COL_FLOAT COL_INT
0 a 2.1 1.0
1 b 4.2 2.0
2 c 6.3 NaN
Wir speichern die DataFrame als Snowflake-Tabelle mit dem Namen pandas_test, die wir in unseren Beispielen verwenden werden.
df.to_snowflake("pandas_test", if_exists='replace',index=False)
Als Nächstes erstellen wir eine DataFrame aus der Snowflake-Tabelle. Wir löschen die Spalte COL_INT und speichern das Ergebnis in Snowflake in einer Spalte namens row_position.
# Create a DataFrame out of a Snowflake table.
df = pd.read_snowflake('pandas_test')
df.shape
(3, 3)
df.head(2)
COL_STR COL_FLOAT COL_INT
0 a 2.1 1
1 b 4.2 2
df.dropna(subset=["COL_FLOAT"], inplace=True)
df
COL_STR COL_FLOAT COL_INT
0 a 2.1 1
1 c 6.3 2
df.shape
(2, 3)
df.dtypes
COL_STR object
COL_FLOAT float64
COL_INT int64
dtype: object
# Save the result back to Snowflake with a row_pos column.
df.reset_index(drop=True).to_snowflake('pandas_test2', if_exists='replace', index=True, index_label=['row_pos'])
Sie erhalten eine neue Tabelle pandas_test2, die wie folgt aussieht:
row_pos COL_STR COL_FLOAT COL_INT
0 1 a 2.0 1
1 2 b 4.0 2
IO (Lesen und Schreiben)¶
# Reading and writing to Snowflake
df = pd.DataFrame({"fruit": ["apple", "orange"], "size": [3.4, 5.4], "weight": [1.4, 3.2]})
df.to_snowflake("test_table", if_exists="replace", index=False )
df_table = pd.read_snowflake("test_table")
# Generate sample CSV file
with open("data.csv", "w") as f:
f.write('fruit,size,weight\napple,3.4,1.4\norange,5.4,3.2')
# Read from local CSV file
df_csv = pd.read_csv("data.csv")
# Generate sample JSON file
with open("data.json", "w") as f:
f.write('{"fruit":"apple", "size":3.4, "weight":1.4},{"fruit":"orange", "size":5.4, "weight":3.2}')
# Read from local JSON file
df_json = pd.read_json('data.json')
# Upload data.json and data.csv to Snowflake stage named @TEST_STAGE
# Read CSV and JSON file from stage
df_csv = pd.read_csv('@TEST_STAGE/data.csv')
df_json = pd.read_json('@TEST_STAGE/data.json')
Weitere Informationen dazu finden Sie unter Eingabe/Ausgabe.
Indizierung¶
df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "z"]})
df.columns
Index(['a', 'b'], dtype='object')
df.index
Index([0, 1, 2], dtype='int8')
df["a"]
0 1
1 2
2 3
Name: a, dtype: int8
df["b"]
0 x
1 y
2 z
Name: b, dtype: object
df.iloc[0,1]
'x'
df.loc[df["a"] > 2]
a b
2 3 z
df.columns = ["c", "d"]
df
c d
0 1 x
1 2 y
2 3 z
df = df.set_index("c")
df
d
c
1 x
2 y
3 z
df.rename(columns={"d": "renamed"})
renamed
c
1 x
2 y
3 z
Fehlende Werte¶
import numpy as np
df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, np.nan, 1],
[np.nan, np.nan, np.nan, np.nan],
[np.nan, 3, np.nan, 4]],
columns=list("ABCD"))
df
A B C D
0 NaN 2.0 NaN 0.0
1 3.0 4.0 NaN 1.0
2 NaN NaN NaN NaN
3 NaN 3.0 NaN 4.0
df.isna()
A B C D
0 True False True False
1 False False True False
2 True True True True
3 True False True False
df.fillna(0)
A B C D
0 0.0 2.0 0.0 0.0
1 3.0 4.0 0.0 1.0
2 0.0 0.0 0.0 0.0
3 0.0 3.0 0.0 4.0
df.dropna(how="all")
A B C D
0 NaN 2.0 NaN 0.0
1 3.0 4.0 NaN 1.0
3 NaN 3.0 NaN 4.0
Typkonvertierung¶
df = pd.DataFrame({"int": [1,2,3], "str": ["4", "5", "6"]})
df
int str
0 1 4
1 2 5
2 3 6
df_float = df.astype(float)
df_float
int str
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
df_float.dtypes
int float64
str float64
dtype: object
pd.to_numeric(df.str)
0 4.0
1 5.0
2 6.0
Name: str, dtype: float64
df = pd.DataFrame({'year': [2015, 2016],
'month': [2, 3],
'day': [4, 5]})
pd.to_datetime(df)
0 2015-02-04
1 2016-03-05
dtype: datetime64[ns]
Binäre Operationen¶
df_1 = pd.DataFrame([[1,2,3],[4,5,6]])
df_2 = pd.DataFrame([[6,7,8]])
df_1.add(df_2)
0 1 2
0 7.0 9.0 11.0
1 NaN NaN NaN
s1 = pd.Series([1, 2, 3])
s2 = pd.Series([2, 2, 2])
s1 + s2
0 3
1 4
2 5
dtype: int64
df = pd.DataFrame({"A": [1,2,3], "B": [4,5,6]})
df["A+B"] = df["A"] + df["B"]
df
A B A+B
0 1 4 5
1 2 5 7
2 3 6 9
Aggregation¶
df = pd.DataFrame([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[np.nan, np.nan, np.nan]],
columns=['A', 'B', 'C'])
df.agg(['sum', 'min'])
A B C
sum 12.0 15.0 18.0
min 1.0 2.0 3.0
df.median()
A 4.0
B 5.0
C 6.0
dtype: float64
Merge¶
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo'],
'value': [1, 2, 3, 5]})
df1
lkey value
0 foo 1
1 bar 2
2 baz 3
3 foo 5
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo'],
'value': [5, 6, 7, 8]})
df2
rkey value
0 foo 5
1 bar 6
2 baz 7
3 foo 8
df1.merge(df2, left_on='lkey', right_on='rkey')
lkey value_x rkey value_y
0 foo 1 foo 5
1 foo 1 foo 8
2 bar 2 bar 6
3 baz 3 baz 7
4 foo 5 foo 5
5 foo 5 foo 8
df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']})
df
key A
0 K0 A0
1 K1 A1
2 K2 A2
3 K3 A3
4 K4 A4
5 K5 A5
other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],
'B': ['B0', 'B1', 'B2']})
df.join(other, lsuffix='_caller', rsuffix='_other')
key_caller A key_other B
0 K0 A0 K0 B0
1 K1 A1 K1 B1
2 K2 A2 K2 B2
3 K3 A3 None None
4 K4 A4 None None
5 K5 A5 None None
Groupby¶
df = pd.DataFrame({'Animal': ['Falcon', 'Falcon','Parrot', 'Parrot'],
'Max Speed': [380., 370., 24., 26.]})
df
Animal Max Speed
0 Falcon 380.0
1 Falcon 370.0
2 Parrot 24.0
3 Parrot 26.0
df.groupby(['Animal']).mean()
Max Speed
Animal
Falcon 375.0
Parrot 25.0
Weitere Informationen dazu finden Sie unter GroupBy.
Pivot¶
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"C": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
"E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
df
A B C D E
0 foo one small 1 2
1 foo one large 2 4
2 foo one large 2 5
3 foo two small 3 5
4 foo two small 3 6
5 bar one large 4 6
6 bar one small 5 8
7 bar two small 6 9
8 bar two large 7 9
pd.pivot_table(df, values='D', index=['A', 'B'],
columns=['C'], aggfunc="sum")
C large small
A B
bar one 4.0 5
two 7.0 6
foo one 4.0 1
two NaN 6
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
'baz': [1, 2, 3, 4, 5, 6],
'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
df
foo bar baz zoo
0 one A 1 x
1 one B 2 y
2 one C 3 z
3 two A 4 q
4 two B 5 w
5 two C 6 t