Verwenden von DataFrames in Snowpark Python

In Snowpark erfolgt die Abfrage und Verarbeitung von Daten hauptsächlich über einen DataFrame. Unter diesem Thema wird erklärt, wie Sie DataFrames verwenden.

Unter diesem Thema:

Verwenden Sie zum Abrufen und Ändern von Daten die Klasse DataFrame . Ein DataFrame repräsentiert ein relationales Dataset, das im Lazy-Modus ausgewertet wird: Es wird nur ausgeführt, wenn eine bestimmte Aktion ausgelöst wird. In gewissem Sinne ist ein DataFrame wie eine Abfrage, die ausgewertet werden muss, um Daten abzurufen.

So rufen Sie Daten in einem DataFrame ab:

  1. Konstruieren Sie ein DataFrame, das die Datenquelle für das Dataset angibt.

    Sie können z. B. einen DataFrame erstellen, der Daten aus einer Tabelle, Daten einer externen CSV-Datei oder die Ausführung einer SQL-Anweisung enthält.

  2. Geben Sie an, wie das Dataset in den DataFrame transformiert werden soll.

    Sie können z. B. angeben, welche Spalten ausgewählt werden sollen, wie die Zeilen gefiltert werden sollen, wie die Ergebnisse sortiert und gruppiert werden sollen usw.

  3. Führen Sie die Anweisung aus, um die Daten in den DataFrame abzurufen.

    Um die Daten in den DataFrame abzurufen, müssen Sie eine Methode aufrufen, die eine Aktion ausführt (z. B. die collect()-Methode).

In den nächsten Abschnitten werden diese Schritte näher erläutert.

Einrichten der Beispiele für diesen Abschnitt

Einige der Beispiele in diesem Abschnitt verwenden einen DataFrame, um eine Tabelle namens sample_product_data abzufragen. Wenn Sie diese Beispiele ausführen möchten, können Sie diese Tabelle erstellen und mit einigen Daten füllen, indem Sie die folgenden SQL-Anweisungen ausführen:

Sie können die SQL-Anweisungen mit Snowpark Python ausführen:

>>> session.sql('CREATE OR REPLACE TABLE sample_product_data (id INT, parent_id INT, category_id INT, name VARCHAR, serial_number VARCHAR, key INT, "3rd" INT)').collect()
[Row(status='Table SAMPLE_PRODUCT_DATA successfully created.')]
>>> session.sql("""
... INSERT INTO sample_product_data VALUES
... (1, 0, 5, 'Product 1', 'prod-1', 1, 10),
... (2, 1, 5, 'Product 1A', 'prod-1-A', 1, 20),
... (3, 1, 5, 'Product 1B', 'prod-1-B', 1, 30),
... (4, 0, 10, 'Product 2', 'prod-2', 2, 40),
... (5, 4, 10, 'Product 2A', 'prod-2-A', 2, 50),
... (6, 4, 10, 'Product 2B', 'prod-2-B', 2, 60),
... (7, 0, 20, 'Product 3', 'prod-3', 3, 70),
... (8, 7, 20, 'Product 3A', 'prod-3-A', 3, 80),
... (9, 7, 20, 'Product 3B', 'prod-3-B', 3, 90),
... (10, 0, 50, 'Product 4', 'prod-4', 4, 100),
... (11, 10, 50, 'Product 4A', 'prod-4-A', 4, 100),
... (12, 10, 50, 'Product 4B', 'prod-4-B', 4, 100)
... """).collect()
[Row(number of rows inserted=12)]
Copy

Um zu überprüfen, ob die Tabelle erstellt wurde, führen Sie folgende Anweisung aus:

>>> session.sql("SELECT count(*) FROM sample_product_data").collect()
[Row(COUNT(*)=12)]
Copy

Einrichten der Beispiele in einem Python-Arbeitsblatt

Um diese Beispiele in einem Python-Arbeitsblatt einzurichten und auszuführen, erstellen Sie die Beispieltabelle und richten Sie Ihr Python-Arbeitsblatt ein.

  1. Erstellen Sie ein SQL-Arbeitsblatt, und führen Sie Folgendes aus:

    CREATE OR REPLACE TABLE sample_product_data
      (id INT, parent_id INT, category_id INT, name VARCHAR, serial_number VARCHAR, key INT, "3rd" INT);
    
    INSERT INTO sample_product_data VALUES
      (1, 0, 5, 'Product 1', 'prod-1', 1, 10),
      (2, 1, 5, 'Product 1A', 'prod-1-A', 1, 20),
      (3, 1, 5, 'Product 1B', 'prod-1-B', 1, 30),
      (4, 0, 10, 'Product 2', 'prod-2', 2, 40),
      (5, 4, 10, 'Product 2A', 'prod-2-A', 2, 50),
      (6, 4, 10, 'Product 2B', 'prod-2-B', 2, 60),
      (7, 0, 20, 'Product 3', 'prod-3', 3, 70),
      (8, 7, 20, 'Product 3A', 'prod-3-A', 3, 80),
      (9, 7, 20, 'Product 3B', 'prod-3-B', 3, 90),
      (10, 0, 50, 'Product 4', 'prod-4', 4, 100),
      (11, 10, 50, 'Product 4A', 'prod-4-A', 4, 100),
      (12, 10, 50, 'Product 4B', 'prod-4-B', 4, 100);
    
    SELECT count(*) FROM sample_product_data;
    
    Copy
  1. Erstellen Sie ein Python-Arbeitsblatt, und legen Sie denselben Datenbank- und Schemakontext fest wie beim SQL-Arbeitsblatt, das Sie zum Erstellen der Tabelle sample_product_data verwendet haben.

Wenn Sie die Beispiele unter diesem Thema in einem Python-Arbeitsblatt verwenden möchten, verwenden Sie das Beispiel innerhalb der Handler-Funktion (z. B. main), und verwenden Sie das Session-Objekt, das an die Funktion übergeben wird, um DataFrameszu erstellen.

Rufen Sie beispielsweise die Methode table des Objekts session auf, um einen DataFrame für eine Tabelle zu erstellen:

import snowflake.snowpark as snowpark
from snowflake.snowpark.functions import col

def main(session: snowpark.Session):
  df_table = session.table("sample_product_data")
Copy

Verwenden Sie die Registerkarte Output, um die von der Funktion generierte Ausgabe zu überprüfen, z. B. durch Aufrufen der show-Methode des DataFrame-Objekts.

Um den von der Funktion zurückgegebenen Wert zu untersuchen, wählen Sie den Datentyp des Rückgabewerts unter Settings » Return type aus, und verwenden Sie die Registerkarte Results wie folgt:

  • Wenn Ihre Funktion einen DataFrame zurückgibt, verwenden Sie den Standard-Rückgabetyp Table.

  • Wenn Ihre Funktion eine Liste (list) von Zeilen (Row) von der collect-Methode eines DataFrame-Objekts zurückgibt, verwenden Sie Variant als Rückgabetyp.

  • Wenn Ihre Funktion einen beliebigen anderen Wert zurückgibt, der in eine Zeichenfolge umgewandelt werden kann, oder wenn Ihre Funktion keinen Wert zurückgibt, verwenden Sie String als Rückgabetyp.

Weitere Informationen dazu finden Sie unter Ausführen von Python-Arbeitsblättern.

Erstellen eines DataFrame

Um einen DataFrame zu erstellen, können Sie die Methoden und Eigenschaften der Session-Klasse verwenden. Jede der folgenden Methoden erstellt einen DataFrame aus einem anderen Typ von Datenquelle:

Sie können diese Beispiele in Ihrer lokalen Entwicklungsumgebung ausführen oder sie innerhalb der main-Funktion aufrufen, die in einem Python-Arbeitsblatt definiert ist.

  • Um einen DataFrame aus Daten einer Tabelle, einer Ansicht oder eines Streams zu erstellen, rufen Sie die table-Methode auf:

    >>> # Create a DataFrame from the data in the "sample_product_data" table.
    >>> df_table = session.table("sample_product_data")
    
    # To print out the first 10 rows, call df_table.show()
    
    Copy
  • Um einen DataFrame aus angegebenen Werten zu erstellen, rufen Sie die create_dataframe-Methode auf:

    >>> # Create a DataFrame with one column named a from specified values.
    >>> df1 = session.create_dataframe([1, 2, 3, 4]).to_df("a")
    >>> df1.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df1
    -------
    |"A"  |
    -------
    |1    |
    |2    |
    |3    |
    |4    |
    -------
    
    Copy

    Erstellen Sie einen DataFrame mit den vier Spalten „a“, „b“, „c“ und „d“:

    >>> # Create a DataFrame with 4 columns, "a", "b", "c" and "d".
    >>> df2 = session.create_dataframe([[1, 2, 3, 4]], schema=["a", "b", "c", "d"])
    >>> df2.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df2
    -------------------------
    |"A"  |"B"  |"C"  |"D"  |
    -------------------------
    |1    |2    |3    |4    |
    -------------------------
    
    Copy

    Erstellen Sie einen weiteren DataFrame mit den vier Spalten „a“, „b“, „c“ und „d“:

    >>> # Create another DataFrame with 4 columns, "a", "b", "c" and "d".
    >>> from snowflake.snowpark import Row
    >>> df3 = session.create_dataframe([Row(a=1, b=2, c=3, d=4)])
    >>> df3.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df3
    -------------------------
    |"A"  |"B"  |"C"  |"D"  |
    -------------------------
    |1    |2    |3    |4    |
    -------------------------
    
    Copy

    Erstellen Sie einen DataFrame, und geben Sie ein Schema an:

    >>> # Create a DataFrame and specify a schema
    >>> from snowflake.snowpark.types import IntegerType, StringType, StructType, StructField
    >>> schema = StructType([StructField("a", IntegerType()), StructField("b", StringType())])
    >>> df4 = session.create_dataframe([[1, "snow"], [3, "flake"]], schema)
    >>> df4.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df4
    ---------------
    |"A"  |"B"    |
    ---------------
    |1    |snow   |
    |3    |flake  |
    ---------------
    
    Copy
  • Um einen DataFrame zu erstellen, der einen Wertebereich enthält, rufen Sie die range-Methode auf:

    >>> # Create a DataFrame from a range
    >>> # The DataFrame contains rows with values 1, 3, 5, 7, and 9 respectively.
    >>> df_range = session.range(1, 10, 2).to_df("a")
    >>> df_range.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_range
    -------
    |"A"  |
    -------
    |1    |
    |3    |
    |5    |
    |7    |
    |9    |
    -------
    
    Copy
  • Um einen DataFrame zu erstellen, der die Daten aus einer in einem Stagingbereich befindlichen Datei enthält, verwenden Sie die Eigenschaft read zum Abrufen eines DataFrameReader-Objekts. Im DataFrameReader-Objekt rufen Sie die Methode auf, die dem Format der Daten in der Datei entspricht:

    >>> from snowflake.snowpark.types import StructType, StructField, StringType, IntegerType
    
    >>> # Create DataFrames from data in a stage.
    >>> df_json = session.read.json("@my_stage2/data1.json")
    >>> df_catalog = session.read.schema(StructType([StructField("name", StringType()), StructField("age", IntegerType())])).csv("@stage/some_dir")
    
    Copy
  • Um einen DataFrame zu erstellen, der die Ergebnisse einer SQL-Abfrage enthält, rufen Sie die sql-Methode auf:

    >>> # Create a DataFrame from a SQL query
    >>> df_sql = session.sql("SELECT name from sample_product_data")
    >>> df_sql.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_sql
    --------------
    |"NAME"      |
    --------------
    |Product 1   |
    |Product 1A  |
    |Product 1B  |
    |Product 2   |
    |Product 2A  |
    |Product 2B  |
    |Product 3   |
    |Product 3A  |
    |Product 3B  |
    |Product 4   |
    --------------
    
    Copy

    Auch wenn es mit der sql-Methode möglich ist, durch Ausführen von SELECT-Anweisungen Daten aus Tabellen und Stagingdateien abzurufen, bietet die Verwendung der Methode table und der Eigenschaft read eine bessere Syntax- und Fehlerhervorhebung sowie intelligente Codevervollständigung in Entwicklungstools.

Festlegen der Transformation des Datasets

Um anzugeben, welche Spalten ausgewählt und wie die Ergebnisse gefiltert, sortiert, gruppiert usw. werden sollen, rufen Sie die DataFrame-Methoden auf, die das Dataset transformieren. Um die Spalten in diesen Methoden zu identifizieren, verwenden Sie die Funktion col oder einen Ausdruck, der eine Spalte ergibt Weitere Informationen dazu finden Sie unter Angeben von Spalten und Ausdrücken.

Beispiel:

  • Zur Angabe der Zeilen, die zurückgegeben werden sollen, rufen Sie die filter-Methode auf:

    >>> # Import the col function from the functions module.
    >>> # Python worksheets import this function by default
    >>> from snowflake.snowpark.functions import col
    
    >>> # Create a DataFrame for the rows with the ID 1
    >>> # in the "sample_product_data" table.
    
    >>> # This example uses the == operator of the Column object to perform an
    >>> # equality check.
    >>> df = session.table("sample_product_data").filter(col("id") == 1)
    >>> df.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df
    ------------------------------------------------------------------------------------
    |"ID"  |"PARENT_ID"  |"CATEGORY_ID"  |"NAME"     |"SERIAL_NUMBER"  |"KEY"  |"3rd"  |
    ------------------------------------------------------------------------------------
    |1     |0            |5              |Product 1  |prod-1           |1      |10     |
    ------------------------------------------------------------------------------------
    
    Copy
  • Zur Angabe der Spalten, die ausgewählt werden sollen, rufen Sie die select-Methode auf:

    >>> # Import the col function from the functions module.
    >>> from snowflake.snowpark.functions import col
    
    >>> # Create a DataFrame that contains the id, name, and serial_number
    >>> # columns in the "sample_product_data" table.
    >>> df = session.table("sample_product_data").select(col("id"), col("name"), col("serial_number"))
    >>> df.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df
    ---------------------------------------
    |"ID"  |"NAME"      |"SERIAL_NUMBER"  |
    ---------------------------------------
    |1     |Product 1   |prod-1           |
    |2     |Product 1A  |prod-1-A         |
    |3     |Product 1B  |prod-1-B         |
    |4     |Product 2   |prod-2           |
    |5     |Product 2A  |prod-2-A         |
    |6     |Product 2B  |prod-2-B         |
    |7     |Product 3   |prod-3           |
    |8     |Product 3A  |prod-3-A         |
    |9     |Product 3B  |prod-3-B         |
    |10    |Product 4   |prod-4           |
    ---------------------------------------
    
    Copy
  • Sie können auch wie folgt auf Spalten verweisen:

    >>> # Import the col function from the functions module.
    >>> from snowflake.snowpark.functions import col
    
    >>> df_product_info = session.table("sample_product_data")
    >>> df1 = df_product_info.select(df_product_info["id"], df_product_info["name"], df_product_info["serial_number"])
    >>> df2 = df_product_info.select(df_product_info.id, df_product_info.name, df_product_info.serial_number)
    >>> df3 = df_product_info.select("id", "name", "serial_number")
    
    Copy

Jede Methode gibt ein neues DataFrame-Objekt zurück, das transformiert wurde. Die Methode hat keine Auswirkungen auf das ursprüngliche DataFrame-Objekt. Wenn Sie mehrere Transformationen anwenden möchten, können Sie Methodenaufrufe verketten, sodass jede nachfolgende Transformationsmethode auf dem neuen DataFrame-Objekt ausgeführt wird, das vom vorherigen Methodenaufruf zurückgegeben wurde.

Diese Transformationsmethoden geben an, wie die SQL-Anweisung erstellt wird, sie rufen keine Daten aus der Snowflake-Datenbank ab. Die unter Ausführen einer Aktion zum Auswerten eines DataFrame beschriebenen Aktionsmethoden führen den Datenabruf aus.

Verknüpfen von DataFrames

Zum Verknüpfen von DataFrame-Objekten rufen Sie die join-Methode auf:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # Create a DataFrame that joins the two DataFrames
>>> # on the column named "key".
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].as_("key"), "value1", "value2").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].as_("key"), "value1", "value2")
-------------------------------
|"KEY"  |"VALUE1"  |"VALUE2"  |
-------------------------------
|a      |1         |3         |
|b      |2         |4         |
-------------------------------
Copy

Wenn beide DataFrames die gleiche Spalte für die Verknüpfung haben, können Sie die folgende Beispielsyntax verwenden:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # If both dataframes have the same column "key", the following is more convenient.
>>> df_lhs.join(df_rhs, ["key"]).show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, ["key"])
-------------------------------
|"KEY"  |"VALUE1"  |"VALUE2"  |
-------------------------------
|a      |1         |3         |
|b      |2         |4         |
-------------------------------
Copy

Sie können auch den &-Operator verwenden, um Join-Ausdrücke zu verbinden:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # Use & operator connect join expression. '|' and ~ are similar.
>>> df_joined_multi_column = df_lhs.join(df_rhs, (df_lhs.col("key") == df_rhs.col("key")) & (df_lhs.col("value1") < df_rhs.col("value2"))).select(df_lhs["key"].as_("key"), "value1", "value2")
>>> df_joined_multi_column.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_joined_multi_column
-------------------------------
|"KEY"  |"VALUE1"  |"VALUE2"  |
-------------------------------
|a      |1         |3         |
|b      |2         |4         |
-------------------------------
Copy

Wenn Sie eine Selbstverknüpfung (Self-Join) ausführen möchten, müssen Sie den DataFrame kopieren:

>>> # copy the DataFrame if you want to do a self-join
>>> from copy import copy

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs_copied = copy(df_lhs)
>>> df_self_joined = df_lhs.join(df_lhs_copied, (df_lhs.col("key") == df_lhs_copied.col("key")) & (df_lhs.col("value1") == df_lhs_copied.col("value1")))
Copy

Wenn es in den DataFrames sich überlappende Spalten gibt, stellt Snowpark den Spalten im Verknüpfungsergebnis ein zufällig generiertes Präfix voran:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).show()  
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"))
-----------------------------------------------------
|"l_av5t_KEY"  |"VALUE1"  |"r_1p6k_KEY"  |"VALUE2"  |
-----------------------------------------------------
|a             |1         |a             |3         |
|b             |2         |b             |4         |
-----------------------------------------------------
Copy

Sie können die überlappenden Spalten mit Column.alias umbenennen:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].alias("key1"), df_rhs["key"].alias("key2"), "value1", "value2").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].alias("key1"), df_rhs["key"].alias("key2"), "value1", "value2")
-----------------------------------------
|"KEY1"  |"KEY2"  |"VALUE1"  |"VALUE2"  |
-----------------------------------------
|a       |a       |1         |3         |
|b       |b       |2         |4         |
-----------------------------------------
Copy

Um zufällige Präfixe zu vermeiden, können Sie auch ein Suffix angeben, das an die sich überschneidenden Spalten angehängt wird:

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"), lsuffix="_left", rsuffix="_right").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"), lsuffix="_left", rsuffix="_right")
--------------------------------------------------
|"KEY_LEFT"  |"VALUE1"  |"KEY_RIGHT"  |"VALUE2"  |
--------------------------------------------------
|a           |1         |a            |3         |
|b           |2         |b            |4         |
--------------------------------------------------
Copy

In diesen Beispielen wird DataFrame.col verwendet, um die in der Verknüpfung zu verwendenden Spalten anzugeben. Weitere Möglichkeiten zum Angeben von Spalten finden Sie unter Angeben von Spalten und Ausdrücken.

Wenn Sie eine Tabelle mit sich selbst über verschiedene Spalten verknüpfen müssen, können Sie die Selbstverknüpfung (Self-Join) nicht mit einem einzelnen DataFrame durchführen. Im folgenden Beispiel wird ein einzelner DataFrame in einer Selbstverknüpfung verwendet. Diese Ausführung schlägt fehl, weil die Spaltenausdrücke für "id" sowohl auf der linken als auch der rechten Seite der Verknüpfung vorhanden sind:

>>> from snowflake.snowpark.exceptions import SnowparkJoinException

>>> df = session.table("sample_product_data")
>>> # This fails because columns named "id" and "parent_id"
>>> # are in the left and right DataFrames in the join.
>>> try:
...     df_joined = df.join(df, col("id") == col("parent_id")) # fails
... except SnowparkJoinException as e:
...     print(e.message)
You cannot join a DataFrame with itself because the column references cannot be resolved correctly. Instead, create a copy of the DataFrame with copy.copy(), and join the DataFrame with this copy.
>>> # This fails because columns named "id" and "parent_id"
>>> # are in the left and right DataFrames in the join.
>>> try:
...     df_joined = df.join(df, df["id"] == df["parent_id"])   # fails
... except SnowparkJoinException as e:
...     print(e.message)
You cannot join a DataFrame with itself because the column references cannot be resolved correctly. Instead, create a copy of the DataFrame with copy.copy(), and join the DataFrame with this copy.
Copy

Verwenden Sie stattdessen die in Python integrierte copy()-Methode, um einen Klon des DataFrame-Objekts zu erstellen, und verwenden Sie dann die beiden DataFrame-Objekte für die Verknüpfung:

>>> from copy import copy

>>> # Create a DataFrame object for the "sample_product_data" table for the left-hand side of the join.
>>> df_lhs = session.table("sample_product_data")
>>> # Clone the DataFrame object to use as the right-hand side of the join.
>>> df_rhs = copy(df_lhs)

>>> # Create a DataFrame that joins the two DataFrames
>>> # for the "sample_product_data" table on the
>>> # "id" and "parent_id" columns.
>>> df_joined = df_lhs.join(df_rhs, df_lhs.col("id") == df_rhs.col("parent_id"))
>>> df_joined.count()
8
Copy

Angeben von Spalten und Ausdrücken

Wenn Sie diese Transformationsmethoden aufrufen, müssen Sie möglicherweise Spalten angeben oder Ausdrücke, die Spalten verwenden. Wenn Sie z. B. die select-Methode aufrufen, müssen Sie die Spalten angeben, die ausgewählt werden sollen.

Um auf eine Spalte zu verweisen, erstellen Sie ein Column-Objekt durch Aufruf der Funktion col im snowflake.snowpark.functions-Modul.

>>> # Import the col function from the functions module.
>>> from snowflake.snowpark.functions import col

>>> df_product_info = session.table("sample_product_data").select(col("id"), col("name"))
>>> df_product_info.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_product_info
---------------------
|"ID"  |"NAME"      |
---------------------
|1     |Product 1   |
|2     |Product 1A  |
|3     |Product 1B  |
|4     |Product 2   |
|5     |Product 2A  |
|6     |Product 2B  |
|7     |Product 3   |
|8     |Product 3A  |
|9     |Product 3B  |
|10    |Product 4   |
---------------------
Copy

Bemerkung

Weitere Informationen zum Erstellen eines Column-Objekts für ein Literal finden Sie unter Verwenden von Literalen als Spaltenobjekte.

Wenn Sie einen Filter, eine Projektion, eine Verknüpfungsbedingung usw. angeben müssen, können Sie Column-Objekte in einem Ausdruck verwenden. Beispiel:

  • Sie können Column-Objekte mit der Methode filter verwenden, um eine Filterbedingung anzugeben:

    >>> # Specify the equivalent of "WHERE id = 20"
    >>> # in a SQL SELECT statement.
    >>> df_filtered = df.filter(col("id") == 20)
    
    Copy
    >>> df = session.create_dataframe([[1, 3], [2, 10]], schema=["a", "b"])
    >>> # Specify the equivalent of "WHERE a + b < 10"
    >>> # in a SQL SELECT statement.
    >>> df_filtered = df.filter((col("a") + col("b")) < 10)
    >>> df_filtered.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_filtered
    -------------
    |"A"  |"B"  |
    -------------
    |1    |3    |
    -------------
    
    Copy
  • Sie können Column-Objekte mit der Methode select verwenden, um einen Alias zu definieren:

    >>> df = session.create_dataframe([[1, 3], [2, 10]], schema=["a", "b"])
    >>> # Specify the equivalent of "SELECT b * 10 AS c"
    >>> # in a SQL SELECT statement.
    >>> df_selected = df.select((col("b") * 10).as_("c"))
    >>> df_selected.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_selected
    -------
    |"C"  |
    -------
    |30   |
    |100  |
    -------
    
    Copy
  • Sie können Column Objekte mit der Methode join verwenden, um eine Verknüpfungsbedingung zu definieren:

    >>> dfX = session.create_dataframe([[1], [2]], schema=["a_in_X"])
    >>> dfY = session.create_dataframe([[1], [3]], schema=["b_in_Y"])
    >>> # Specify the equivalent of "X JOIN Y on X.a_in_X = Y.b_in_Y"
    >>> # in a SQL SELECT statement.
    >>> df_joined = dfX.join(dfY, col("a_in_X") == col("b_in_Y")).select(dfX["a_in_X"].alias("the_joined_column"))
    >>> df_joined.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_joined
    -----------------------
    |"THE_JOINED_COLUMN"  |
    -----------------------
    |1                    |
    -----------------------
    
    Copy

Wenn Sie auf Spalten in zwei verschiedenen DataFrame-Objekten verweisen müssen, die denselben Namen haben (z. B. beim Verknüpfen von DataFrames über diese Spalte), können Sie die DataFrame.col-Methode in einem der beiden DataFrame-Objekte verwenden, um sich auf eine Spalte in diesem Objekt zu beziehen (z. B. df1.col("name") und df2.col("name")).

Im folgenden Beispiel wird gezeigt, wie Sie mit der DataFrame.col-Methode auf eine Spalte in einem bestimmten DataFrame verweisen. Im Beispiel werden zwei DataFrame-Objekte verknüpft, die beide eine Spalte mit dem Namen key haben. Dabei wird im Beispiel die Column.as-Methode verwendet, um die Namen der Spalten im neu erstellten DataFrame zu ändern.

>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value"])
>>> # Create a DataFrame that joins two other DataFrames (df_lhs and df_rhs).
>>> # Use the DataFrame.col method to refer to the columns used in the join.
>>> df_joined = df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs.col("key").as_("key"), df_lhs.col("value").as_("L"), df_rhs.col("value").as_("R"))
>>> df_joined.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_joined
---------------------
|"KEY"  |"L"  |"R"  |
---------------------
|a      |1    |3    |
|b      |2    |4    |
---------------------
Copy

Verwenden von doppelten Anführungszeichen um Objektbezeichner (Tabellennamen, Spaltennamen usw.)

Die Namen von Datenbanken, Schemas, Tabellen und Stagingbereichen, die Sie angeben, müssen den Snowflake-Anforderungen an Bezeichner entsprechen.

Erstellen Sie eine Tabelle mit Spalten, in denen die Groß-/Kleinschreibung unterschieden wird:

>>> session.sql("""
... create or replace temp table "10tablename"(
... id123 varchar, -- case insensitive because it's not quoted.
... "3rdID" varchar, -- case sensitive.
... "id with space" varchar -- case sensitive.
... )""").collect()
>>> # Add return to the statement to return the collect() results in a Python worksheet
[Row(status='Table 10tablename successfully created.')]
Copy

Fügen Sie dann Werte zur Tabelle hinzu:

>>> session.sql("""insert into "10tablename" (id123, "3rdID", "id with space") values ('a', 'b', 'c')""").collect()
>>> # Add return to the statement to return the collect() results in a Python worksheet
[Row(number of rows inserted=1)]
Copy

Erstellen Sie dann einen DataFrame für die Tabelle, und fragen Sie die Tabelle ab:

>>> df = session.table('"10tablename"')
>>> df.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df
---------------------------------------
|"ID123"  |"3rdID"  |"id with space"  |
---------------------------------------
|a        |b        |c                |
---------------------------------------
Copy

Wenn Sie einen Namen angeben, geht Snowflake davon aus, dass der Name in Großbuchstaben geschrieben ist. Daher sind z. B. die folgenden Aufrufe gleichwertig:

>>> df.select(col("id123")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(ID123='a')]
>>> df.select(col("ID123")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(ID123='a')]
Copy

Wenn der Name nicht den Anforderungen für Bezeichner entspricht, müssen Sie den Namen in doppelte Anführungszeichen (") setzen. Verwenden Sie einen Backslash (\) als Escape-Zeichen zum Umschließen von doppelten Anführungszeichen innerhalb von Zeichenfolgenliteralen. Der folgende Tabellenname beginnt z. B. nicht mit einem Buchstaben oder einem Unterstrich, sodass Sie den Namen in doppelte Anführungszeichen setzen müssen:

>>> df = session.table("\"10tablename\"")
Copy

Alternativ können Sie anstelle von Backslashes auch einfache Anführungszeichen als Escapezeichen für doppelte Anführungszeichen in einem Zeichenfolgenliteral verwenden.

>>> df = session.table('"10tablename"')
Copy

Beachten Sie, dass Sie bei der Angabe des Namens einer Spalte keine doppelten Anführungszeichen um den Namen verwenden müssen. Die Snowpark-Bibliothek schließt Spaltennamen automatisch in doppelte Anführungszeichen ein, wenn der Name nicht den Bezeichneranforderungen entspricht:

>>> df.select(col("3rdID")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(3rdID='b')]
>>> df.select(col("\"3rdID\"")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(3rdID='b')]
Copy

Daher sind z. B. die folgenden Aufrufe äquivalent:

>>> df.select(col("id with space")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
>>> df.select(col("\"id with space\"")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
Copy

Wenn Sie bereits doppelte Anführungszeichen um einen Spaltennamen hinzugefügt haben, fügt die Bibliothek keine weiteren doppelten Anführungszeichen um den Namen ein.

In einigen Fällen kann der Spaltenname doppelte Anführungszeichen enthalten:

>>> session.sql('''
... create or replace temp table quoted(
... "name_with_""air""_quotes" varchar,
... """column_name_quoted""" varchar
... )''').collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Table QUOTED successfully created.')]
Copy
>>> session.sql('''insert into quoted ("name_with_""air""_quotes", """column_name_quoted""") values ('a', 'b')''').collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(number of rows inserted=1)]
Copy

Wie unter Anforderungen an Bezeichner erläutert, müssen Sie für jedes doppelte Anführungszeichen innerhalb eines in Anführungszeichen geschriebenen Bezeichners zwei doppelte Anführungszeichen verwenden (z. B. "name_with_""air""_quotes" und """column_name_quoted"""):

>>> df_table = session.table("quoted")
>>> df_table.select("\"name_with_\"\"air\"\"_quotes\"").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(name_with_"air"_quotes='a')]
Copy
>>> df_table.select("\"\"\"column_name_quoted\"\"\"").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row("column_name_quoted"='b')]
Copy

Wenn ein Bezeichner in doppelte Anführungszeichen eingeschlossen ist (unabhängig davon, ob Sie die Anführungszeichen explizit hinzugefügt haben oder die Bibliothek die Anführungszeichen für Sie hinzugefügt hat), berücksichtigt Snowflake die Groß-/Kleinschreibung des Bezeichners:

>>> # The following calls are NOT equivalent!
>>> # The Snowpark library adds double quotes around the column name,
>>> # which makes Snowflake treat the column name as case-sensitive.
>>> df.select(col("id with space")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
Copy

Im Vergleich zu folgendem Beispiel:

>>> from snowflake.snowpark.exceptions import SnowparkSQLException
>>> try:
...     df.select(col("ID WITH SPACE")).collect()
... except SnowparkSQLException as e:
...     print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 7
invalid identifier '"ID WITH SPACE"'
Copy

Verwenden von Literalen als Spaltenobjekte

Um ein Literal in einer Methode zu verwenden, die ein Column-Objekt als Argument erwartet, erstellen Sie ein Column-Objekt für das Literal, indem Sie das Literal an die lit-Funktion im snowflake.snowpark.functions-Modul übergeben. Beispiel:

>>> # Import for the lit and col functions.
>>> from snowflake.snowpark.functions import col, lit

>>> # Show the first 10 rows in which num_items is greater than 5.
>>> # Use `lit(5)` to create a Column object for the literal 5.
>>> df_filtered = df.filter(col("num_items") > lit(5))
Copy

Umwandeln eines Spaltenobjekts in einen bestimmten Typ

Um ein Column-Objekt in einen bestimmten Typ umzuwandeln, rufen Sie die cast-Methode auf, und übergeben Sie ein Typobjekt aus dem snowflake.snowpark.types-Modul. So können Sie zum Beispiel ein Literal in NUMBER mit einer Gesamtstellenzahl (precision) von 5 und einer Dezimalstellenzahl (scale) von 2 umwandeln:

>>> # Import for the lit function.
>>> from snowflake.snowpark.functions import lit

>>> # Import for the DecimalType class.
>>> from snowflake.snowpark.types import DecimalType

>>> decimal_value = lit(0.05).cast(DecimalType(5,2))
Copy

Verketten von Methodenaufrufen

Da jede Methode, die ein DataFrame-Objekt transformiert, ein neues DataFrame-Objekt zurückgibt, auf das die Transformation angewendet wurde, können Sie Methodenaufrufe verketten, um ein neues DataFrame zu erstellen, das auf eine andere Weise transformiert wird.

Im folgenden Beispiel wird ein DataFrame zurückgegeben, der für folgende Aufgaben konfiguriert ist:

  • Abfragen der Tabelle sample_product_data

  • Rückgabe der Zeile mit id = 1

  • Auswahl der Spalten name und serial_number

    >>> df_product_info = session.table("sample_product_data").filter(col("id") == 1).select(col("name"), col("serial_number"))
    >>> df_product_info.show()
    >>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
    >>> # return df_product_info
    -------------------------------
    |"NAME"     |"SERIAL_NUMBER"  |
    -------------------------------
    |Product 1  |prod-1           |
    -------------------------------
    
    Copy

In diesem Beispiel:

  • session.table("sample_product_data") gibt einen DataFrame für die Tabelle sample_product_data zurück.

    Der DataFrame enthält zwar noch nicht die Daten aus der Tabelle, aber das Objekt enthält die Definitionen der Spalten in der Tabelle.

  • filter(col("id") == 1) gibt ein DataFrame für die Tabelle sample_product_data zurück, die so eingerichtet ist, dass sie die Zeile mit id = 1 zurückgibt.

    Beachten Sie, dass der DataFrame noch nicht die übereinstimmende Zeile aus der Tabelle enthält. Die übereinstimmende Zeile wird erst abgerufen, wenn Sie eine Aktionsmethode aufrufen.

  • select(col("name"), col("serial_number")) gibt ein DataFrame zurück, das die Spalten name und serial_number für die Zeile in der Tabelle sample_product_data enthält, die id = 1 hat.

Beim Verketten von Methodenaufrufen ist die Reihenfolge der Aufrufe von Bedeutung. Jeder Methodenaufruf gibt ein DataFrame zurück, das transformiert wurde. Stellen Sie sicher, dass nachfolgende Aufrufe das transformierte DataFrame verwenden.

Im folgenden Beispiel gibt die Methode select ein DataFrame zurück, das nur zwei Spalten enthält: name und serial_number. Der Aufruf der filter-Methode auf diesem DataFrame schlägt fehl, weil dieser die Spalte id verwendet, die im transformierten DataFrame nicht vorhanden ist.

>>> # This fails with the error "invalid identifier 'ID'."
>>> df_product_info = session.table("sample_product_data").select(col("name"), col("serial_number")).filter(col("id") == 1)
>>> try:
...   df_product_info.show()
... except SnowparkSQLException as e:
...   print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 121
invalid identifier 'ID'
Copy

Im Gegensatz dazu wird der folgende Code erfolgreich ausgeführt, weil die filter()-Methode auf einem DataFrame aufgerufen wird, der alle Spalten der Tabelle sample_product_data einschließlich der Spalte id enthält:

>>> # This succeeds because the DataFrame returned by the table() method
>>> # includes the "id" column.
>>> df_product_info = session.table("sample_product_data").filter(col("id") == 1).select(col("name"), col("serial_number"))
>>> df_product_info.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_product_info
-------------------------------
|"NAME"     |"SERIAL_NUMBER"  |
-------------------------------
|Product 1  |prod-1           |
-------------------------------
Copy

Beim Verwenden von Snowpark Python müssen Sie die Methodenaufrufe select und filter möglicherweise in einer anderen Reihenfolge ausführen als bei Verwendung der entsprechenden Schlüsselwörter (SELECT und WHERE) in einer SQL-Anweisung.

Abrufen von Spaltendefinitionen

Um die Definition der Spalten im Dataset für den DataFrame abzurufen, rufen Sie die schema-Eigenschaft auf. Diese Methode gibt ein StructType-Objekt zurück, das ein list von StructField-Objekten enthält. Jedes StructField-Objekt enthält die Definition einer Spalte.

# Import the StructType
from snowflake.snowpark.types import *
# Get the StructType object that describes the columns in the
# underlying rowset.
table_schema = session.table("sample_product_data").schema
table_schema
StructType([StructField('ID', LongType(), nullable=True), StructField('PARENT_ID', LongType(), nullable=True), StructField('CATEGORY_ID', LongType(), nullable=True), StructField('NAME', StringType(), nullable=True), StructField('SERIAL_NUMBER', StringType(), nullable=True), StructField('KEY', LongType(), nullable=True), StructField('"3rd"', LongType(), nullable=True)])
Copy

Im zurückgegebenen StructType-Objekt sind die Spaltennamen immer normalisiert. Bezeichner, die nicht mit Anführungszeichen umschlossen sind, werden in Großbuchstaben zurückgegeben. Bezeichner in Anführungszeichen werden genau in der Schreibweise zurückgegeben, in der sie definiert wurden.

Im folgenden Beispiel wird ein DataFrame erstellt zurück, der die Spalten mit den Namen ID und 3rd enthält. Für den Spaltennamen 3rd schließt die Snowpark-Bibliothek den Namen automatisch in doppelte Anführungszeichen ein ("3rd"), da der Name nicht den Anforderungen an einen Bezeichner entspricht.

Im Beispiel wird erst die schema-Eigenschaft aufgerufen und dann die names-Eigenschaft auf dem zurückgegebenen StructType-Objekt, um ein list-Objekt mit den Spaltennamen zu erhalten. Die Namen werden in dem von der schema-Eigenschaft zurückgegebenen StructType-Objekt normalisiert.

>>> # Create a DataFrame containing the "id" and "3rd" columns.
>>> df_selected_columns = session.table("sample_product_data").select(col("id"), col("3rd"))
>>> # Print out the names of the columns in the schema. This prints out:
>>> # This prints List["ID", "\"3rd\""]
>>> df_selected_columns.schema.names
['ID', '"3rd"']
Copy

Ausführen einer Aktion zum Auswerten eines DataFrame

Wie bereits erwähnt, wird der DataFrame im Lazy-Modus ausgewertet, d. h. die SQL-Anweisung wird erst dann zur Ausführung an den Server gesendet, wenn Sie eine Aktion ausführen. Eine Aktion löst die Auswertung des DataFrame aus und sendet die entsprechende SQL-Anweisung zur Ausführung an den Server.

Die folgenden Methoden führen eine Aktion aus:

Klasse

Methode

Beschreibung

DataFrame

collect

Wertet den DataFrame aus und gibt das resultierende Dataset als ein list von Row-Objekten zurück.

DataFrame

count

Wertet den DataFrame aus und gibt die Anzahl der Zeilen zurück.

DataFrame

show

Wertet den DataFrame aus und gibt die Zeilen auf der Konsole aus. Bei dieser Methode ist die Anzahl der Zeilen (standardmäßig) auf 10 begrenzt.

DataFrameWriter

save_as_table

Speichert die im DataFrame enthaltenen Daten in die angegebene Tabelle. Weitere Informationen dazu finden Sie unter Speichern von Daten in eine Tabelle.

Beispiel: Um eine Abfrage auf einer Tabelle auszuführen und die Ergebnisse zurückzugeben, rufen Sie die collect-Methode auf:

>>> # Create a DataFrame with the "id" and "name" columns from the "sample_product_data" table.
>>> # This does not execute the query.
>>> df = session.table("sample_product_data").select(col("id"), col("name"))

>>> # Send the query to the server for execution and
>>> # return a list of Rows containing the results.
>>> results = df.collect()
>>> # Use a return statement to return the collect() results in a Python worksheet
>>> # return results
Copy

Um die Abfrage auszuführen und die Anzahl der Ergebnisse zurückzugeben, rufen Sie die count-Methode auf:

>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")

>>> # Send the query to the server for execution and
>>> # print the count of rows in the table.
>>> print(df_products.count())
12
Copy

Um eine Abfrage auszuführen und die Ergebnisse über die Konsole auszugeben, rufen Sie die show-Methode auf:

>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")

>>> # Send the query to the server for execution and
>>> # print the results to the console.
>>> # The query limits the number of rows to 10 by default.
>>> df_products.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_products
-------------------------------------------------------------------------------------
|"ID"  |"PARENT_ID"  |"CATEGORY_ID"  |"NAME"      |"SERIAL_NUMBER"  |"KEY"  |"3rd"  |
-------------------------------------------------------------------------------------
|1     |0            |5              |Product 1   |prod-1           |1      |10     |
|2     |1            |5              |Product 1A  |prod-1-A         |1      |20     |
|3     |1            |5              |Product 1B  |prod-1-B         |1      |30     |
|4     |0            |10             |Product 2   |prod-2           |2      |40     |
|5     |4            |10             |Product 2A  |prod-2-A         |2      |50     |
|6     |4            |10             |Product 2B  |prod-2-B         |2      |60     |
|7     |0            |20             |Product 3   |prod-3           |3      |70     |
|8     |7            |20             |Product 3A  |prod-3-A         |3      |80     |
|9     |7            |20             |Product 3B  |prod-3-B         |3      |90     |
|10    |0            |50             |Product 4   |prod-4           |4      |100    |
-------------------------------------------------------------------------------------
Copy

So begrenzen Sie die Anzahl der Zeilen auf 20:

>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")

>>> # Limit the number of rows to 20, rather than 10.
>>> df_products.show(20)
>>> # All rows are returned when you use return in a Python worksheet to return the DataFrame as a table
>>> # return df_products
-------------------------------------------------------------------------------------
|"ID"  |"PARENT_ID"  |"CATEGORY_ID"  |"NAME"      |"SERIAL_NUMBER"  |"KEY"  |"3rd"  |
-------------------------------------------------------------------------------------
|1     |0            |5              |Product 1   |prod-1           |1      |10     |
|2     |1            |5              |Product 1A  |prod-1-A         |1      |20     |
|3     |1            |5              |Product 1B  |prod-1-B         |1      |30     |
|4     |0            |10             |Product 2   |prod-2           |2      |40     |
|5     |4            |10             |Product 2A  |prod-2-A         |2      |50     |
|6     |4            |10             |Product 2B  |prod-2-B         |2      |60     |
|7     |0            |20             |Product 3   |prod-3           |3      |70     |
|8     |7            |20             |Product 3A  |prod-3-A         |3      |80     |
|9     |7            |20             |Product 3B  |prod-3-B         |3      |90     |
|10    |0            |50             |Product 4   |prod-4           |4      |100    |
|11    |10           |50             |Product 4A  |prod-4-A         |4      |100    |
|12    |10           |50             |Product 4B  |prod-4-B         |4      |100    |
-------------------------------------------------------------------------------------
Copy

Bemerkung

Wenn Sie die schema-Eigenschaft aufrufen, um die Definitionen der Spalten im DataFrame zu erhalten, müssen Sie keine Aktionsmethode aufrufen.

Inhalt des DataFrame als Pandas DataFrame zurückgeben

Um den Inhalt eines DataFrame als Pandas DataFrame zurückzugeben, verwenden Sie die to_pandas-Methode.

Beispiel:

>>> python_df = session.create_dataframe(["a", "b", "c"])
>>> pandas_df = python_df.to_pandas()
Copy

Speichern von Daten in eine Tabelle

So speichern Sie den Inhalt eines DataFrame in eine Tabelle:

  1. Rufen Sie die Eigenschaft write auf, um ein DataFrameWriter-Objekt zu erhalten.

  2. Rufen Sie die Methode mode im Objekt DataFrameWriter auf, und geben Sie den Modus an. Weitere Informationen dazu finden Sie in der API-Dokumentation. Diese Methode gibt ein neues DataFrameWriter-Objekt zurück, das mit dem angegebenen Modus konfiguriert ist.

  3. Rufen Sie die Methode save_as_table im DataFrameWriter-Objekt auf, um den Inhalt des DataFrame in der angegebenen Tabelle zu speichern.

Beachten Sie, dass Sie keine separate Methode (z. B. collect) aufrufen müssen, um die SQL-Anweisung auszuführen, mit der Daten in der Tabelle gespeichert werden.

Beispiel:

>>> df.write.mode("overwrite").save_as_table("table1")
Copy

Erstellen einer Ansicht aus einem DataFrame

Um aus einem DataFrame eine Ansicht zu erstellen, rufen Sie die Methode create_or_replace_view auf, die unmittelbar eine neue Ansicht erstellt:

>>> import os
>>> database = os.environ["snowflake_database"]  # use your own database and schema
>>> schema = os.environ["snowflake_schema"]
>>> view_name = "my_view"
>>> df.create_or_replace_view(f"{database}.{schema}.{view_name}")
[Row(status='View MY_VIEW successfully created.')]
Copy

Da Sie das Arbeitsblatt in einem Python-Arbeitsblatt im Kontext einer Datenbank und eines Schemas ausführen, können Sie zum Erstellen einer Ansicht Folgendes ausführen:

# Define a DataFrame
df_products = session.table("sample_product_data")
# Define a View name
view_name = "my_view"
# Create the view
df_products.create_or_replace_view(f"{view_name}")
# return the view name
return view_name + " successfully created"
my_view successfully created
Copy

Ansichten, die Sie durch Aufruf von create_or_replace_view erstellen, sind persistent. Wenn Sie diese Ansicht nicht mehr benötigen, können Sie die Ansicht manuell löschen.

Alternativ können Sie auch die Methode create_or_replace_temp_view verwenden, die eine temporäre Ansicht erstellt. Die temporäre Ansicht ist nur in der Sitzung verfügbar, in der sie erstellt wurde.

Verwenden von Dateien in Stagingbereichen

In diesem Abschnitt wird erläutert, wie Sie Daten in einer Datei abfragen, die sich in einem Snowflake-Stagingbereich befindet. Für andere Operationen auf Dateien verwenden Sie SQL-Anweisungen.

Um Daten in Dateien abzufragen, die sich in einem Snowflake-Stagingbereich befinden, verwenden Sie die Klasse DataFrameReader:

  1. Rufen Sie die Methode read der Session-Klasse auf, um auf ein DataFrameReader-Objekt zuzugreifen.

  2. Wenn die Dateien im CSV-Format sind, beschreiben Sie die Felder in der Datei. Gehen Sie dabei wie folgt vor:

    1. Erstellen Sie ein StructType-Objekt, das aus einem list-Objekt von StructField-Objekten besteht, die die Felder in der Datei beschreiben.

    2. Geben Sie für jedes StructField-Objekt Folgendes an:

      • Name des Feldes

      • Datentyp des Feldes (angegeben als Objekt im snowflake.snowpark.types-Modul)

      • Ob das Feld nullwertfähig ist oder nicht

      Beispiel:

      >>> from snowflake.snowpark.types import *
      
      >>> schema_for_data_file = StructType([
      ...                          StructField("id", StringType()),
      ...                          StructField("name", StringType())
      ...                       ])
      
      Copy
    3. Rufen Sie die schema-Eigenschaft im DataFrameReader-Objekt auf, und übergeben Sie dabei das StructType-Objekt.

      Beispiel:

      >>> df_reader = session.read.schema(schema_for_data_file)
      
      Copy

      Die schema-Methode gibt ein DataFrameReader-Objekt zurück, das so konfiguriert ist, dass es Dateien liest, die die angegebenen Felder enthalten.

      Beachten Sie, dass Sie dies für Dateien in anderen Formaten (z. B. JSON) nicht tun müssen. Für solche Dateien behandelt der DataFrameReader die Daten als ein einzelnes Feld vom Typ VARIANT mit dem Feldnamen $1.

  3. Wenn Sie zusätzliche Informationen darüber angeben müssen, wie die Daten gelesen werden sollen (z. B. dass die Daten komprimiert sind oder dass eine CSV-Datei ein Semikolon statt eines Kommas zum Begrenzen von Feldern verwendet), rufen Sie die Methode option oder options des DataFrameReader-Objekts auf.

    Die option-Methode nimmt den Namen und den Wert der Option entgegen, die Sie festlegen möchten, und ermöglicht es Ihnen, mehrere verkettete Aufrufe zu kombinieren, während die options-Methode ein Wörterbuch mit den Namen der Optionen und den entsprechenden Werten annimmt.

    Die Namen und Werte der Dateiformatoptionen finden Sie in der Dokumentation zu CREATE FILE FORMAT.

    Sie können auch die in der COPY INTO TABLE-Dokumentation beschriebenen Kopieroptionen einstellen. Beachten Sie, dass die Einstellung von Kopieroptionen zu einer teureren Ausführungsstrategie führen kann, wenn Sie die Daten in den DataFrame abrufen.

    Im folgenden Beispiel wird das DataFrameReader-Objekt für die Abfrage von Daten einer CSV-Datei eingerichtet, die nicht komprimiert ist und die ein Semikolon als Feldbegrenzer verwendet.

    >>> df_reader = df_reader.option("field_delimiter", ";").option("COMPRESSION", "NONE")
    
    Copy

    Die Methoden option und options geben ein DataFrameReader-Objekt zurück, das mit den angegebenen Optionen konfiguriert ist.

  4. Rufen Sie die Methode auf, die dem Format der Datei entspricht (z. B. die Methode csv), und übergeben Sie dabei den Speicherort der Datei.

    >>> df = df_reader.csv("@s3_ts_stage/emails/data_0_0_0.csv")
    
    Copy

    Die Methoden, die dem Format einer Datei entsprechen, geben ein DataFrame-Objekt zurück, das so konfiguriert ist, dass es die Daten aus dieser Datei enthält.

  5. Verwenden Sie die DataFrame-Objektmethoden, um alle Transformationen auszuführen, die für das Dataset benötigt werden (Auswahl bestimmter Felder, Filtern von Zeilen usw.).

    Im folgenden Beispiel wird das Element color aus einer JSON-Datei extrahiert, die sich im Stagingbereich my_stage befindet:

    >>> # Import the sql_expr function from the functions module.
    >>> from snowflake.snowpark.functions import sql_expr
    
    >>> df = session.read.json("@my_stage").select(sql_expr("$1:color"))
    
    Copy

    Wie bereits erläutert, werden Daten in Dateien, die nicht im CSV-Format sind (z. B. JSON), von DataFrameReader als eine einzelne VARIANT-Spalte mit dem Namen $1 behandelt.

    In diesem Beispiel wird die Funktion sql_expr im snowflake.snowpark.functions-Modul verwendet, um den Pfad zum Element color anzugeben.

    Beachten Sie, dass die Funktion sql_expr das Eingangsargument weder interpretiert noch verändert. Mit der Funktion können Sie lediglich Ausdrücke und Snippets in SQL konstruieren, die noch nicht von der Snowpark-API unterstützt werden.

  6. Rufen Sie eine Aktionsmethode auf, um die Daten in der Datei abzufragen.

    Wie bei DataFrames für Tabellen werden die Daten erst dann in den DataFrame abgerufen, wenn Sie eine Aktionsmethode aufrufen.

Verwenden von semistrukturierten Daten

Mit einem DataFrame können Sie semistrukturierte Daten abfragen und darauf zugreifen (z. B. JSON-Daten). In den nächsten Abschnitten wird erläutert, wie semistrukturierte Daten in einem DataFrame verwendet werden:

Bemerkung

Die Beispiele in diesen Abschnitten verwenden die Beispieldaten aus In Beispielen verwendete Beispieldaten.

Durchsuchen semistrukturierter Daten

Um auf ein bestimmtes Feld oder Element in semistrukturierten Daten zu verweisen, verwenden Sie die folgenden Methoden des Column-Objekts:

  • Rufen Sie das Attribut col_object["<Feldname>"] ab, um ein Column-Objekt für ein Feld in einem OBJECT (oder ein VARIANT, das ein OBJECT enthält) zurückzugeben.

  • Verwenden Sie col_object[<Index>], um ein Column-Objekt für ein Element in einem ARRAY (oder ein VARIANT, das ein ARRAY enthält) zurückzugeben.

Bemerkung

Wenn der Feldname oder die Elemente im Pfad unregelmäßig sind und die Verwendung der oben beschriebenen Indexierung erschweren, können Sie als Alternative get, get_ignore_case oder get_path verwenden.

Im folgenden Code wird beispielsweise das Feld dealership in Objekten der Spalte src der Beispieldaten ausgewählt:

>>> from snowflake.snowpark.functions import col

>>> df = session.table("car_sales")
>>> df.select(col("src")["dealership"]).show()
Copy

Der Code gibt Folgendes aus:

----------------------------
|"""SRC""['DEALERSHIP']"   |
----------------------------
|"Valley View Auto Sales"  |
|"Tindel Toyota"           |
----------------------------
Copy

Bemerkung

Die Werte in DataFrame sind von doppelten Anführungszeichen umgeben, da diese Werte als Zeichenfolgenliterale zurückgegeben werden. Weitere Informationen zum Umwandeln dieser Werte in einen bestimmten Typ finden Sie unter Explizites Umwandeln von Werten semistrukturierter Daten.

Sie können auch Methodenaufrufe verketten, um einen Pfad zu einem bestimmten Feld oder Element zu durchlaufen.

Im folgende Code wird zum Beispiel das Feld name im Objekt salesperson ausgewählt:

>>> df = session.table("car_sales")
>>> df.select(df["src"]["salesperson"]["name"]).show()
Copy

Der Code gibt Folgendes aus:

------------------------------------
|"""SRC""['SALESPERSON']['NAME']"  |
------------------------------------
|"Frank Beasley"                   |
|"Greg Northrup"                   |
------------------------------------
Copy

In einem weiteren Codebeispiel wird das erste Element des Feldes vehicle ausgewählt, das eine Reihe von Fahrzeugen enthält. Im Beispiel wird auch das Feld price aus dem ersten Element ausgewählt.

>>> df = session.table("car_sales")
>>> df.select(df["src"]["vehicle"][0]).show()
>>> df.select(df["src"]["vehicle"][0]["price"]).show()
Copy

Der Code gibt Folgendes aus:

---------------------------
|"""SRC""['VEHICLE'][0]"  |
---------------------------
|{                        |
|  "extras": [            |
|    "ext warranty",      |
|    "paint protection"   |
|  ],                     |
|  "make": "Honda",       |
|  "model": "Civic",      |
|  "price": "20275",      |
|  "year": "2017"         |
|}                        |
|{                        |
|  "extras": [            |
|    "ext warranty",      |
|    "rust proofing",     |
|    "fabric protection"  |
|  ],                     |
|  "make": "Toyota",      |
|  "model": "Camry",      |
|  "price": "23500",      |
|  "year": "2017"         |
|}                        |
---------------------------

------------------------------------
|"""SRC""['VEHICLE'][0]['PRICE']"  |
------------------------------------
|"20275"                           |
|"23500"                           |
------------------------------------
Copy

Wenn der Feldname oder die Elemente im Pfad unregelmäßig sind, können Sie für den oben beschriebenen Zugriff auf Felder alternativ auch die Funktion get, get_ignore_case oder get_path verwenden.

Die folgenden Codezeilen geben zum Beispiel beide den Wert eines bestimmten Feldes in einem Objekt aus:

>>> from snowflake.snowpark.functions import get, get_path, lit

>>> df.select(get(col("src"), lit("dealership"))).show()
>>> df.select(col("src")["dealership"]).show()
Copy

In ähnlicher Weise geben die folgenden Codezeilen beide den Wert eines Feldes für einen bestimmten Pfad in einem Objekt aus:

>>> df.select(get_path(col("src"), lit("vehicle[0].make"))).show()
>>> df.select(col("src")["vehicle"][0]["make"]).show()
Copy

Explizites Umwandeln von Werten semistrukturierter Daten

Standardmäßig werden die Werte von Feldern und Elementen als Zeichenfolgenliterale (einschließlich der doppelten Anführungszeichen) zurückgegeben, wie in den obigen Beispielen gezeigt.

Um unerwartete Ergebnisse zu vermeiden, rufen Sie die Methode cast auf, um den Wert in einen ganz bestimmten Typ umzuwandeln. Mit dem folgenden Code werden zum Beispiel die Werte ohne und mit Umwandlung ausgegeben:

>>> # Import the objects for the data types, including StringType.
>>> from snowflake.snowpark.types import *

>>> df = session.table("car_sales")
>>> df.select(col("src")["salesperson"]["id"]).show()
>>> df.select(col("src")["salesperson"]["id"].cast(StringType())).show()
Copy

Der Code gibt Folgendes aus:

----------------------------------
|"""SRC""['SALESPERSON']['ID']"  |
----------------------------------
|"55"                            |
|"274"                           |
----------------------------------

---------------------------------------------------
|"CAST (""SRC""['SALESPERSON']['ID'] AS STRING)"  |
---------------------------------------------------
|55                                               |
|274                                              |
---------------------------------------------------
Copy

Vereinfachen eines Arrays von Objekten zu Zeilen

Wenn Sie semistrukturierte Daten für einen DataFrame vereinfachen müssen (um z. B. für jedes Objekt in einem Array eine Zeile zu erstellen), rufen Sie flatten unter Verwendung der Methode join_table_function auf. Diese Methode entspricht der SQL-Funktion FLATTEN. Wenn Sie einen Pfad zu einem Objekt oder Array übergeben, gibt die Methode ein DataFrame zurück, das eine Zeile für jedes Feld oder Element im Objekt oder Array enthält.

In den Beispieldaten ist beispielsweise src:customer ein Array von Objekten, die Informationen über einen Kunden enthalten. Jedes Objekt enthält ein Feld name und ein Feld address.

Wenn Sie diesen Pfad an die Funktion flatten übergeben:

>>> df = session.table("car_sales")
>>> df.join_table_function("flatten", col("src")["customer"]).show()
Copy

Dann gibt diese Methode einen DataFrame zurück:

----------------------------------------------------------------------------------------------------------------------------------------------------------
|"SRC"                                      |"SEQ"  |"KEY"  |"PATH"  |"INDEX"  |"VALUE"                            |"THIS"                               |
----------------------------------------------------------------------------------------------------------------------------------------------------------
|{                                          |1      |NULL   |[0]     |0        |{                                  |[                                    |
|  "customer": [                            |       |       |        |         |  "address": "San Francisco, CA",  |  {                                  |
|    {                                      |       |       |        |         |  "name": "Joyce Ridgely",         |    "address": "San Francisco, CA",  |
|      "address": "San Francisco, CA",      |       |       |        |         |  "phone": "16504378889"           |    "name": "Joyce Ridgely",         |
|      "name": "Joyce Ridgely",             |       |       |        |         |}                                  |    "phone": "16504378889"           |
|      "phone": "16504378889"               |       |       |        |         |                                   |  }                                  |
|    }                                      |       |       |        |         |                                   |]                                    |
|  ],                                       |       |       |        |         |                                   |                                     |
|  "date": "2017-04-28",                    |       |       |        |         |                                   |                                     |
|  "dealership": "Valley View Auto Sales",  |       |       |        |         |                                   |                                     |
|  "salesperson": {                         |       |       |        |         |                                   |                                     |
|    "id": "55",                            |       |       |        |         |                                   |                                     |
|    "name": "Frank Beasley"                |       |       |        |         |                                   |                                     |
|  },                                       |       |       |        |         |                                   |                                     |
|  "vehicle": [                             |       |       |        |         |                                   |                                     |
|    {                                      |       |       |        |         |                                   |                                     |
|      "extras": [                          |       |       |        |         |                                   |                                     |
|        "ext warranty",                    |       |       |        |         |                                   |                                     |
|        "paint protection"                 |       |       |        |         |                                   |                                     |
|      ],                                   |       |       |        |         |                                   |                                     |
|      "make": "Honda",                     |       |       |        |         |                                   |                                     |
|      "model": "Civic",                    |       |       |        |         |                                   |                                     |
|      "price": "20275",                    |       |       |        |         |                                   |                                     |
|      "year": "2017"                       |       |       |        |         |                                   |                                     |
|    }                                      |       |       |        |         |                                   |                                     |
|  ]                                        |       |       |        |         |                                   |                                     |
|}                                          |       |       |        |         |                                   |                                     |
|{                                          |2      |NULL   |[0]     |0        |{                                  |[                                    |
|  "customer": [                            |       |       |        |         |  "address": "New York, NY",       |  {                                  |
|    {                                      |       |       |        |         |  "name": "Bradley Greenbloom",    |    "address": "New York, NY",       |
|      "address": "New York, NY",           |       |       |        |         |  "phone": "12127593751"           |    "name": "Bradley Greenbloom",    |
|      "name": "Bradley Greenbloom",        |       |       |        |         |}                                  |    "phone": "12127593751"           |
|      "phone": "12127593751"               |       |       |        |         |                                   |  }                                  |
|    }                                      |       |       |        |         |                                   |]                                    |
|  ],                                       |       |       |        |         |                                   |                                     |
|  "date": "2017-04-28",                    |       |       |        |         |                                   |                                     |
|  "dealership": "Tindel Toyota",           |       |       |        |         |                                   |                                     |
|  "salesperson": {                         |       |       |        |         |                                   |                                     |
|    "id": "274",                           |       |       |        |         |                                   |                                     |
|    "name": "Greg Northrup"                |       |       |        |         |                                   |                                     |
|  },                                       |       |       |        |         |                                   |                                     |
|  "vehicle": [                             |       |       |        |         |                                   |                                     |
|    {                                      |       |       |        |         |                                   |                                     |
|      "extras": [                          |       |       |        |         |                                   |                                     |
|        "ext warranty",                    |       |       |        |         |                                   |                                     |
|        "rust proofing",                   |       |       |        |         |                                   |                                     |
|        "fabric protection"                |       |       |        |         |                                   |                                     |
|      ],                                   |       |       |        |         |                                   |                                     |
|      "make": "Toyota",                    |       |       |        |         |                                   |                                     |
|      "model": "Camry",                    |       |       |        |         |                                   |                                     |
|      "price": "23500",                    |       |       |        |         |                                   |                                     |
|      "year": "2017"                       |       |       |        |         |                                   |                                     |
|    }                                      |       |       |        |         |                                   |                                     |
|  ]                                        |       |       |        |         |                                   |                                     |
|}                                          |       |       |        |         |                                   |                                     |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Copy

Von diesem DataFrame aus können Sie die Felder name und address jedes Objekts im Feld VALUE auswählen:

>>> df.join_table_function("flatten", col("src")["customer"]).select(col("value")["name"], col("value")["address"]).show()
Copy
-------------------------------------------------
|"""VALUE""['NAME']"   |"""VALUE""['ADDRESS']"  |
-------------------------------------------------
|"Joyce Ridgely"       |"San Francisco, CA"     |
|"Bradley Greenbloom"  |"New York, NY"          |
-------------------------------------------------
Copy

Der folgende Code ergänzt das vorherige Beispiel, indem die Werte in einen bestimmten Typ umgewandelt und die Namen der Spalten geändert werden:

>>> df.join_table_function("flatten", col("src")["customer"]).select(col("value")["name"].cast(StringType()).as_("Customer Name"), col("value")["address"].cast(StringType()).as_("Customer Address")).show()
Copy
-------------------------------------------
|"Customer Name"     |"Customer Address"  |
-------------------------------------------
|Joyce Ridgely       |San Francisco, CA   |
|Bradley Greenbloom  |New York, NY        |
-------------------------------------------
Copy

Ausführen von SQL-Anweisungen

Um eine von Ihnen angegebene SQL-Anweisung auszuführen, rufen Sie die Methode sql in der Klasse Session auf und übergeben die auszuführende Anweisung. Diese Methode gibt einen DataFrame zurück.

Beachten Sie, dass die SQL-Anweisung erst ausgeführt wird, wenn Sie eine Aktionsmethode aufrufen.

>>> # Get the list of the files in a stage.
>>> # The collect() method causes this SQL statement to be executed.
>>> session.sql("create or replace temp stage my_stage").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Stage area MY_STAGE successfully created.')]

>>> stage_files_df = session.sql("ls @my_stage").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
>>> # Resume the operation of a warehouse.
>>> # Note that you must call the collect method to execute
>>> # the SQL statement.
>>> session.sql("alter warehouse if exists my_warehouse resume if suspended").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Statement executed successfully.')]

>>> # Set up a SQL statement to copy data from a stage to a table.
>>> session.sql("copy into sample_product_data from @my_stage file_format=(type = csv)").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Copy executed with 0 files processed.')]
Copy

Wenn Sie Methoden zur Transformation des DataFrame aufrufen möchten (z. B. filter, select usw.), beachten Sie, dass diese Methoden nur funktionieren, wenn die zugrunde liegende SQL-Anweisung eine SELECT-Anweisung ist. Die Transformationsmethoden werden für andere Arten von SQL-Anweisungen nicht unterstützt.

>>> df = session.sql("select id, parent_id from sample_product_data where id < 10")
>>> # Because the underlying SQL statement for the DataFrame is a SELECT statement,
>>> # you can call the filter method to transform this DataFrame.
>>> results = df.filter(col("id") < 3).select(col("id")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet

>>> # In this example, the underlying SQL statement is not a SELECT statement.
>>> df = session.sql("ls @my_stage")
>>> # Calling the filter method results in an error.
>>> try:
...   df.filter(col("size") > 50).collect()
... except SnowparkSQLException as e:
...   print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 104
invalid identifier 'SIZE'
Copy