pandas on Snowflake

Mit pandas on Snowflake können Sie Ihren pandas-Code in einer verteilten Weise direkt auf Ihren Daten in Snowflake ausführen. Durch Ändern der Importanweisung und einiger Zeilen Code erhalten Sie das vertraute pandas-Erlebnis, das Sie kennen und lieben, mit den Skalierbarkeits- und Sicherheitsvorteilen von Snowflake. Mit pandas on Snowflake können Sie mit viel größeren Datensätzen arbeiten und vermeiden den Zeit- und Kostenaufwand für die Portierung Ihrer pandas-Pipelines auf andere Big Data-Frameworks oder die Bereitstellung großer und teurer Rechner. Es führt Arbeitslasten nativ in Snowflake durch Transpilierung nach SQL aus, so dass es die Vorteile der Parallelisierung und der Data Governance und Sicherheit von Snowflake nutzen kann. pandas on Snowflake wird über die Snowpark pandas API als Teil der Snowpark Python-Bibliothek 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.

  • Sicherheit und Governance – Die Daten verlassen die sichere Plattform von Snowflake nicht. pandas on Snowflake ermöglicht eine Vereinheitlichung des Datenzugriffs innerhalb von Organisationen und erleichtert die Prüfung und Governance.

  • 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.

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

  • Ihr Arbeitsablauf hat auftragsbezogene Anforderungen, die von pandas-DataFrames unterstützt werden. Zum Beispiel müssen die Datensätze während des gesamten Arbeitsablaufs in der gleichen Reihenfolge angeordnet sein

  • Sie bevorzugen die genauere Code-Vervollständigung von AI-basierten Copilot-Tools

Erste Schritte mit pandas on Snowflake

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]"
Copy

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
Copy

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 the Snowpark plugin for modin.
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')

# Alternatively, 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"])

# Inspect the DataFrame
df
Copy
      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"]
Copy
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()
Copy
  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"]
Copy
LOCATION
Big Bear     9.0
Tahoe        8.0
Whistler    32.5
Name: SNOWFALL, dtype: float64

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.

Sie können die folgenden Operationen verwenden, um Konvertierungen zwischen Snowpark-DataFrames und Snowpark pandas-DataFrames durchzuführen:

Operation

Eingabe

Ausgabe

Anmerkungen

to_snowpark_pandas

Snowpark DataFrame

Snowpark pandas-DataFrame

Diese Operation weist jeder Zeile eine implizite Reihenfolge zu und behält diese Reihenfolge während der Lebensdauer des DataFrame bei. Bei dieser Konvertierung fallen E/A-Kosten an.

to_snowpark

Snowpark pandas-DataFrame oder Snowpark pandas Series

Snowpark DataFrame

Bei dieser Operation wird die Zeilenreihenfolge nicht beibehalten, und der resultierende Snowpark-DataFrame arbeitet mit einem Daten-Snapshot des Snowpark pandas-Quell-DataFrame. Im Gegensatz zu Snowpark-DataFrames, die direkt aus der Tabelle erstellt werden, bedeutet dieses Verhalten, dass Änderungen an der zugrunde liegenden Tabelle bei der Evaluation der Snowpark-Operationen nicht berücksichtigt werden. Es können keine DDL-Operationen und beschränkte DML-Operationen auf DataFrame angewendet werden. Bei dieser Konvertierung fallen keine E/A-Kosten an.

Wann immer es möglich ist, raten wir Ihnen, read_snowflake zu verwenden, um die Tabelle direkt aus Snowflake zu lesen, anstatt sie in und aus Snowpark DataFrame zu konvertieren, und um unnötige Kosten für die Konvertierung zu vermeiden.

Weitere Informationen dazu finden Sie unter Snowpark DataFrames vs Snowpark pandas DataFrame: Was sollte ich wählen?.

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 (pandas 2.2.1) 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.

Wie natives pandas kennt auch pandas on Snowflake Indexe und behält die Zeilenreihenfolge bei. Ihre unterschiedlichen Ausführungsumgebungen verursachen jedoch gewisse nuancierte Unterschiede in ihrem Verhalten. In diesem Abschnitt finden Sie die wichtigsten Unterschiede, auf die Sie achten sollten.

pandas on Snowflake wird am besten mit Daten verwendet, die bereits in Snowflake vorhanden sind, aber Sie können die folgenden Operationen verwenden, um zwischen nativen pandas und pandas on Snowflake zu konvertieren:

Operation

Eingabe

Ausgabe

Anmerkungen

to_pandas

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.

pd.DataFrame(…)

Native pandas DataFrame, Rohdaten, Snowpark pandas-Objekt

Snowpark pandas-DataFrame

Dies sollte für kleine DataFrames reserviert sein. Die Erstellung eines DataFrame mit großen Mengen lokaler Daten führt zu einer temporären Tabelle und kann aufgrund des Hochladens von Daten zu Leistungsproblemen führen.

session.write_pandas

Native pandas DataFrame, Snowpark pandas-Objekt

Snowflake-Tabelle

Das Ergebnis kann anschließend mit pd.read_snowflake unter Verwendung des im Aufruf write_pandas angegebenen Tabellennamens in pandas on Snowflake geladen werden.

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 ermöglicht. 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, Series oder Index), erfolgt immer eine Eager-Evaluation. Beispiel:

    • read_snowflake

    • to_snowflake

    • to_pandas

    • to_dict

    • to_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

bool, BooleanDtype

BOOLEAN

str, StringDtype

STRING

datetime.time

TIME

datetime.date

DATE

Alle Zeitzonen-unabhängigen datetime-Typen

TIMESTAMP_NTZ

Alle Zeitzonen-kompatiblen datetime-Typen

TIMESTAMP_TZ

list, tuple, array

ARRAY

dict, json

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 (df.dtypes)

NUMBER (scale = 0)

int64

NUMBER (scale > 0), REAL

float64

BOOLEAN

bool

STRING, TEXT

object (str)

VARIANT, BINARY, GEOMETRY, GEOGRAPHY

object

ARRAY

object (list)

OBJECT

object (dict)

TIME

object (datetime.time)

TIMESTAMP, TIMESTAMP_NTZ, TIMESTAMP_LTZ, TIMESTAMP_TZ

datetime64[ns]

DATE

object (datetime.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, sodass 1 + True den Wert 2 zurü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, sodass 1 + True zu 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 Python None, np.nan, pd.NaN, pd.NA und pd.NaT als 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 wieder NaN, NA und NaT von 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: Python 3.9, 3.10 oder 3.11, modin Version 0.28.1 und pandas Version 2.2.1 sind erforderlich.

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:

  1. 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.9 zu erstellen, geben Sie Folgendes ein:

    conda create --name snowpark_pandas python=3.9
    conda activate snowpark_pandas
    
    Copy

    Bemerkung

    Wenn Sie zuvor eine ältere Version von pandas on Snowflake mit Python 3.8 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.9, 3.10 oder 3.11 aus.

  2. Installieren Sie die Snowpark Python-Bibliothek mit Modin.

    pip install "snowflake-snowpark-python[modin]"
    
    Copy

    oder

    conda install snowflake-snowpark-python modin==0.28.1
    
    Copy

Bemerkung

Stellen Sie sicher, dass snowflake-snowpark-python Version 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')
Copy

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()
Copy

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>"
Copy

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]])
Copy

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])
Copy

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])
Copy

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])
Copy

Bemerkung

Sie müssen die Sitzung, die für einen neuen Snowpark pandas DataFrame oder Series verwendet wird, über modin.pandas.session einstellen. 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:

Verwendung von pandas on Snowflake mit Snowflake Notebooks

Um pandas on Snowflake in Snowflake-Notebooks zu verwenden, siehe pandas on Snowflake in Notebooks.

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.

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'])
Copy

Um die gespeicherte Prozedur aufzurufen, können Sie dt_pipeline_sproc() in Python oder CALL run_data_transformation_pipeline_sp() in SQL ausführen.

Um die gespeicherte Prozedur als Aufgabe zu planen, können Sie die Snowflake Python API verwenden, um eine Aufgabe zu erstellen.

Verwendung von pandas on Snowflake mit Bibliotheken von Drittanbietern

Wenn Sie die Bibliothek eines Drittanbieters APIs mit einem Snowpark-Pandas DataFrame aufrufen, empfehlen wir, das Snowpark pandas DataFrame in ein pandas DataFrame zu konvertieren, indem Sie to_pandas() aufrufen, bevor Sie DataFrame an die Bibliothek des Drittanbieters übergeben.

Bemerkung

Wenn Sie to_pandas() aufrufen, werden Ihre Daten aus Snowflake in den Speicher gezogen, was Sie bei großen Datensätzen und sensiblen Anwendungsfällen beachten sollten.

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()
Copy
    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
# Convert to pandas DataFrame
train_df_pandas = train.to_pandas()
survived_per_age_plot = alt.Chart(train_df_pandas).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
)
survived_per_age_plot
Copy
altair

Wir können nun scikit-learn verwenden, um nach der Konvertierung in Pandas ein einfaches Modell zu trainieren.

feature_cols = ['Pclass', 'Parch']
# Convert features DataFrame to pandas DataFrames
X_pandas = train_snowpark_pandas.loc[:, feature_cols].to_pandas()
# Convert labels Series to pandas Series
y_pandas = train_snowpark_pandas["Survived"].to_pandas()

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)
Copy
scikit-Modell

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. Wenn MultiIndex verwendet wird, wird ein natives Pandas MultiIndex-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 NotImplementedError ausgelöst. Operationen, die keine verteilte Implementierung haben, greifen auf eine gespeicherte Prozedur zurück. Weitere Informationen zur Unterstützung von APIs finden Sie in der API-Referenzdokumentation.

  • pandas on Snowflake erfordert eine bestimmte Version von pandas. pandas on Snowflake erfordert pandas 2.2.1 und bietet nur Kompatibilität mit pandas 2.2.1.

  • pandas on Snowflake kann nicht innerhalb der pandas on Snowflake apply()-Funktion referenziert werden. Sie können native Pandas nur innerhalb von apply() verwenden.

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()
    
    Copy
  • 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 Sitzungsrichtlinien.

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, iterrows und iteritems. 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)],
      },
)
Copy
  • Vermeiden Sie den Aufruf von apply, applymap oder transform, 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 von df.groupby('col1').apply('sum') den direkten Aufruf df.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. Die Snapshot-Funktion steht jedoch nur für reguläre Snowflake-Tabellen unter normalen Datenbanken zur Verfügung. Es wird eine zusätzliche Materialisierung zu regulären Snowflake-Tabellen eingeführt, wenn Tabellen mit Typen wie Hybrid, Iceberg usw. oder Tabellen unter gemeinsam genutzten Datenbanken geladen werden. Der Snapshot ist erforderlich, um die Datenkonsistenz und die Reihenfolge der Daten zu gewährleisten. Es gibt derzeit keine andere Möglichkeit, die zusätzliche Materialisierung zu umgehen. Bitte verwenden Sie so weit wie möglich normale Snowflake-Tabellen, wenn Sie pandas on Snowflake einsetzen.

  • Überprüfen Sie den Ergebnistyp, bevor Sie mit anderen Operationen fortfahren, und führen Sie bei Bedarf eine explizite Typumwandlung mit astype aus.

    Aufgrund der begrenzten Fähigkeit zur Typinferenz gibt df.apply bei fehlendem Typhinweis Ergebnisse vom Typ Objekt (Variant) zurück, auch wenn das Ergebnis nur Integer-Werte enthält. Wenn andere Operationen erfordern, dass dtype int ist, können Sie eine explizite Typumwandlung ausführen, indem Sie die Methode astype aufrufen, 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 Series oder Dataframe zurü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_result verwendet 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)
    
    Copy

    Im obigen Beispiel ist die Abfrage zum Erstellen von df2 teuer im Computing und wird sowohl beim Erstellen von df3 als auch von df4 wiederverwendet. Die Materialisierung von df2 in eine temporäre Tabelle (sodass nachfolgende Operationen mit df2 ein 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)
    
    Copy

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

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
Copy
(3, 3)
df.head(2)
Copy
    COL_STR  COL_FLOAT  COL_INT
0         a        2.1        1
1         b        4.2        2
df.dropna(subset=["COL_FLOAT"], inplace=True)

df
Copy
    COL_STR  COL_FLOAT  COL_INT
0         a        2.1        1
1         c        6.3        2
df.shape
Copy
(2, 3)
df.dtypes
Copy
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'])
Copy

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')
Copy

Weitere Informationen dazu finden Sie unter Eingabe/Ausgabe.

Indizierung

df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "z"]})
df.columns
Copy
Index(['a', 'b'], dtype='object')
df.index
Copy
Index([0, 1, 2], dtype='int8')
df["a"]
Copy
0    1
1    2
2    3
Name: a, dtype: int8
df["b"]
Copy
0    x
1    y
2    z
Name: b, dtype: object
df.iloc[0,1]
Copy
'x'
df.loc[df["a"] > 2]
Copy
a  b
2  3  z
df.columns = ["c", "d"]
df
Copy
     c  d
0    1  x
1    2  y
2    3  z
df = df.set_index("c")
df
Copy
   d
c
1  x
2  y
3  z
df.rename(columns={"d": "renamed"})
Copy
    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
Copy
     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()
Copy
       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)
Copy
     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")
Copy
     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
Copy
   int str
0    1   4
1    2   5
2    3   6
df_float = df.astype(float)
df_float
Copy
   int  str
0  1.0  4.0
1  2.0  5.0
2  3.0  6.0
df_float.dtypes
Copy
int    float64
str    float64
dtype: object
pd.to_numeric(df.str)
Copy
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)
Copy
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)
Copy
    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
Copy
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
Copy
   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'])
Copy
        A     B     C
sum  12.0  15.0  18.0
min   1.0   2.0   3.0
df.median()
Copy
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
Copy
  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
Copy
  rkey  value
0  foo      5
1  bar      6
2  baz      7
3  foo      8
df1.merge(df2, left_on='lkey', right_on='rkey')
Copy
  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
Copy
  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')
Copy
  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
Copy
   Animal  Max Speed
0  Falcon      380.0
1  Falcon      370.0
2  Parrot       24.0
3  Parrot       26.0
df.groupby(['Animal']).mean()
Copy
        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
Copy
     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")
Copy
    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
Copy
   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

Ressourcen