pandas on Snowflake¶
pandas on Snowflake lets you run your pandas code directly on your data in Snowflake. By simply changing the import statement and a few lines of code, you can get the familiar pandas experience to develop robust pipelines, while seamlessly benefiting from Snowflake’s performance and scalability as your pipelines scale.
Pandas on Snowflake détermine intelligemment s’il faut exécuter le code pandas localement ou utiliser le moteur Snowflake pour se mettre à l’échelle et améliorer les performances grâce à l’exécution hybride. Lorsque vous travaillez avec des ensembles de données volumineux dans Snowflake, les charges de travail sont exécutées en mode natif dans Snowflake via une transpilation vers SQL, ce qui permet de tirer parti de la parallélisation et des avantages de Snowflake en matière de gouvernance et de sécurité des données.
Pandas on Snowflake est livré via l’API Pandas Snowpark dans le cadre de la bibliothèque Snowpark Python, qui permet un traitement évolutif des données du code Python au sein de la plateforme Snowflake.
Avantages de l’utilisation de pandas on Snowflake¶
Meeting Python developers where they are: pandas on Snowflake offers a familiar interface to Python developers by providing a pandas-compatible layer that can run natively in Snowflake.
Scalable distributed pandas: pandas on Snowflake bridges the convenience of pandas with the scalability of Snowflake by leveraging existing query optimization techniques in Snowflake. Minimal code rewrites are required, simplifying the migration journey, so you can seamlessly move from prototype to production.
No additional compute infrastructure to manage and tune: pandas on Snowflake leverages the Snowflake’s powerful compute engine, so you do not need to set up or manage any additional compute infrastructure.
Premiers pas avec pandas on Snowflake¶
Note
Pour un exemple pratique de la façon d’utiliser Pandas on Snowflake, consultez ce notebook et regardez cette vidéo.
Pour installer pandas on Snowflake, vous pouvez utiliser conda ou pip pour installer le paquet. Pour des instructions détaillées, voir Installation.
pip install "snowflake-snowpark-python[modin]"
Une fois pandas on Snowflake installé, au lieu d’importer pandas en tant que import pandas as pd, utilisez les deux lignes suivantes :
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
Here is an example of how you can start using pandas on Snowflake through the pandas on Snowpark Python library with Modin:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
# Create a Snowpark session with a default connection.
from snowflake.snowpark.session import Session
session = Session.builder.create()
# Create a Snowpark pandas DataFrame from existing Snowflake table
df = pd.read_snowflake('SNOWFALL')
# Inspect the DataFrame
df
DAY LOCATION SNOWFALL
0 1 Big Bear 8.0
1 2 Big Bear 10.0
2 3 Big Bear NaN
3 1 Tahoe 3.0
4 2 Tahoe NaN
5 3 Tahoe 13.0
6 1 Whistler NaN
7 Friday Whistler 40.0
8 3 Whistler 25.0
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2
# Inspect the columns after update.
# Note how the data type is updated automatically after transformation.
df["DAY"]
0 1
1 2
2 3
3 1
4 2
5 3
6 1
7 2
8 3
Name: DAY, dtype: int64
# Drop rows with null values.
df.dropna()
DAY LOCATION SNOWFALL
0 1 Big Bear 8.0
1 2 Big Bear 10.0
3 1 Tahoe 3.0
5 3 Tahoe 13.0
7 2 Whistler 40.0
8 3 Whistler 25.0
# Compute the average daily snowfall across locations.
df.groupby("LOCATION").mean()["SNOWFALL"]
LOCATION
Big Bear 9.0
Tahoe 8.0
Whistler 32.5
Name: SNOWFALL, dtype: float64
read_snowflake prend en charge la lecture à partir de vues Snowflake, de tables dynamiques, de tables Iceberg, etc. Vous pouvez également transmettre directement une requête SQL et obtenir un DataFrame Pandas on Snowflake, ce qui permet de passer facilement de SQL à Pandas on Snowflake.
summary_df = pd.read_snowflake("SELECT LOCATION, AVG(SNOWFALL) AS avg_snowfall FROM SNOWFALL GROUP BY LOCATION")
summary_df
Comment fonctionne l’exécution hybride¶
Note
À partir de la version 1.40.0 de Snowpark Python, l’exécution hybride est activée par défaut lors de l’utilisation de Pandas on Snowflake.
Pandas on Snowflake utilise l’exécution hybride pour déterminer s’il faut exécuter le code pandas localement ou utiliser le moteur Snowflake pour se mettre à l’échelle et améliorer les performances. Cela vous permet de continuer à écrire du code pandas habituel pour développer des pipelines robustes, sans avoir à réfléchir au moyen le plus optimal et le plus efficace d’exécuter votre code, tout en bénéficiant des performances et de l’évolutivité de Snowflake à mesure que leurs pipelines évoluent.
Exemple 1 : Créer un petit DataFrame de 11 lignes en ligne. Avec l’exécution hybride, Snowflake sélectionne un backend pandas local, en mémoire, pour exécuter l’opération :
# Create a basic dataframe with 11 rows
df = pd.DataFrame([
("New Year's Day", "2025-01-01"),
("Martin Luther King Jr. Day", "2025-01-20"),
("Presidents' Day", "2025-02-17"),
("Memorial Day", "2025-05-26"),
("Juneteenth National Independence Day", "2025-06-19"),
("Independence Day", "2025-07-04"),
("Labor Day", "2025-09-01"),
("Columbus Day", "2025-10-13"),
("Veterans Day", "2025-11-11"),
("Thanksgiving Day", "2025-11-27"),
("Christmas Day", "2025-12-25")
], columns=["Holiday", "Date"])
# Print out the backend used for this dataframe
df.get_backend()
# >> Output: 'Pandas'
Exemple 2 : Initialiser une table contenant 10 millions de lignes de transactions
# Create a 10M row table in Snowflake and populate with sythentic data
session.sql('''CREATE OR REPLACE TABLE revenue_transactions (Transaction_ID STRING, Date DATE, Revenue FLOAT);''').collect()
session.sql('''SET num_days = (SELECT DATEDIFF(DAY, '2024-01-01', CURRENT_DATE));''').collect()
session.sql('''INSERT INTO revenue_transactions (Transaction_ID, Date, Revenue) SELECT UUID_STRING() AS Transaction_ID, DATEADD(DAY, UNIFORM(0, $num_days, RANDOM()), '2024-01-01') AS Date, UNIFORM(10, 1000, RANDOM()) AS Revenue FROM TABLE(GENERATOR(ROWCOUNT => 10000000));''').collect()
# Read Snowflake table as Snowpark pandas dataframe
df_transactions = pd.read_snowflake("REVENUE_TRANSACTIONS")
Vous pouvez voir que la table exploite Snowflake comme backend, car il s’agit d’une grande table qui réside dans Snowflake.
print(f"The dataset size is {len(df_transactions)} and the data is located in {df_transactions.get_backend()}.")
# >> Output: The dataset size is 10000000 and the data is located in Snowflake.
#Perform some operations on 10M rows with Snowflake
df_transactions["DATE"] = pd.to_datetime(df_transactions["DATE"])
df_transactions.groupby("DATE").sum()["REVENUE"]
Exemple 3 : Filtrer les données et effectuer une agrégation groupby résultant en 7 lignes de données.
Lorsque les données sont filtrées, Snowflake reconnaît implicitement le choix du backend de changements de moteur de Snowflake vers Pandas, puisque la sortie n’est que de 7 lignes de données.
# Filter to data in last 7 days
df_transactions_filter1 = df_transactions[(df_transactions["DATE"] >= pd.Timestamp.today().date() - pd.Timedelta('7 days')) & (df_transactions["DATE"] < pd.Timestamp.today().date())]
# Since filter is not yet evaluated, data stays in Snowflake
assert df_transactions_filter1.get_backend() == "Snowflake"
# After groupby operation, result is transfered from Snowflake to Pandas
df_transactions_filter1.groupby("DATE").sum()["REVENUE"]
Notes and limitations¶
Le type de DataFrame sera toujours
modin.pandas.DataFrame/Series/etcmême lorsque le backend change, pour assurer l’interopérabilité/compatibilité avec le code en aval.Pour déterminer le backend à utiliser, Snowflake utilise parfois une estimation de la taille des lignes au lieu de calculer la longueur exacte du DataFrame à chaque étape. Cela signifie que Snowflake peut ne pas toujours basculer vers le backend optimal immédiatement après une opération lorsque l’ensemble de données devient plus grand/plus petit (par exemple, filtre, agrégation).
Lorsqu’une opération combine deux ou plusieurs DataFrames sur les différents backends, Snowflake détermine où déplacer les données en fonction du coût de transfert des données le plus faible.
Les opérations de filtrage peuvent ne pas entraîner de mouvement de données, car Snowflake peut ne pas être en mesure d’estimer la taille des données filtrées sous-jacentes.
Tout DataFrames composé de données Python en mémoire utilisera le backend pandas, comme ce qui suit :
pd.DataFrame([1])
pd.DataFrame(pandas.DataFrame([1]))
pd.Series({'a': [4]})
An empty DataFrame: pd.DataFrame()
Les DataFrames passeront automatiquement du moteur Snowflake au moteur Pandas sur un ensemble limité d’opérations. Ces opérations comprennent
df.apply,df.plot,df.iterrows,df.itertuples,series.items, ainsi que les opérations de réduction où la taille des données est garantie plus petite. Toutes les opérations ne sont pas prises en charge aux points où la migration des données peut avoir lieu.L’exécution hybride ne déplace pas automatiquement un DataFrame du moteur Pandas vers Snowflake, sauf dans les cas où une opération comme
pd.concatagit sur plusieurs DataFrames.Snowflake ne déplace pas automatiquement un DataFrame du moteur pandas vers Snowflake, à moins qu’une opération comme
pd.concatagit sur plusieurs DataFrames.
When you should use pandas on Snowflake¶
Vous devez utiliser pandas on Snowflake si l’une des conditions suivantes est remplie :
You are familiar with the pandas API and the broader PyData ecosystem.
You work on a team with others who are familiar with pandas and want to collaborate on the same codebase.
You have existing code written in pandas.
You prefer more accurate code completion from AI-based copilot tools.
Pour plus d’informations, voir DataFrames Snowpark contre DataFrame pandas Snowpark : lequel dois-je choisir ?
Utilisation de pandas on Snowflake avec des DataFrames Snowpark¶
L’API pandas on Snowflake et l’API DataFrame sont hautement interopérables, vous pouvez donc créer un pipeline qui exploite ces deux APIs. Pour plus d’informations, voir DataFrames Snowpark contre DataFrame pandas Snowpark : lequel dois-je choisir ?
Vous pouvez utiliser les opérations suivantes pour effectuer des conversions entre des DataFrames Snowpark et des DataFrames Snowpark pandas :
Fonctionnement |
Entrée |
Sortie |
|---|---|---|
DataFrame Snowpark |
DataFrame Snowpark Pandas |
|
DataFrame Snowpark pandas ou Snowpark pandas Series |
DataFrame Snowpark |
Comparaison de pandas on Snowflake et de pandas natif¶
pandas on Snowflake and native pandas have similar DataFrame APIs with matching signatures and similar semantics. pandas on Snowflake provides the same API signature as native pandas and provides scalable computation with Snowflake. pandas on Snowflake respects the semantics described in the native pandas documentation as much as possible, but it uses the Snowflake computation and type system. However, when native pandas executes on a client machine, it uses the Python computation and type system. For information about the type mapping between pandas on Snowflake and Snowflake, see Data types.
Starting with Snowpark Python 1.40.0, pandas on Snowflake is best used with data which is already in Snowflake. To convert between native pandas and pandas on Snowflake type, use the following operations:
Fonctionnement |
Entrée |
Sortie |
|---|---|---|
DataFrame Snowpark Pandas |
Native pandas DataFrame - Materialize all data to the local environment. If the dataset is large, this may result in an out-of-memory error. |
|
DataFrame pandas natif, données brutes, objet pandas Snowpark |
DataFrame Snowpark Pandas |
Environnement d’exécution¶
pandas: Operates on a single machine and processes in-memory data.pandas on Snowflake: Integrates with Snowflake, which allows for distributed computing across a cluster of machines for large datasets, while leveraging in memory pandas for processing small datasets. This integration enables handling of much larger datasets that exceed the memory capacity of a single machine. Note that using the Snowpark pandas API requires a connection to Snowflake.
Lazy versus eager evaluation¶
pandas: Executes operations immediately and materializes results fully in memory after each operation. This eager evaluation of operations might lead to increased memory pressure because data must be moved extensively within a machine.pandas on Snowflake: fournit la même expérience d’API que pandas. Cela imite le modèle d’évaluation exigeante de pandas, mais construit en interne un graphe de requête à évaluation paresseuse pour permettre l’optimisation entre les opérations.La fusion et la transposition des opérations dans un graphe de requêtes offrent des possibilités d’optimisation supplémentaires pour le moteur de calcul distribué Snowflake sous-jacent, ce qui réduit à la fois le coût et la durée d’exécution du pipeline de bout en bout par rapport à l’exécution de pandas directement dans Snowflake.
Note
I/O-related APIs and APIs whose return value is not a Snowpark pandas object (that is,
DataFrame,SeriesorIndex) always evaluate eagerly. For example:read_snowflaketo_snowflaketo_pandasto_dictto_list__repr__The dunder method,
__array__which can be called automatically by some third-party libraries such as scikit-learn. Calls to this method will materialize results to the local machine.
Source et stockage des données¶
pandas: prend en charge les différents lecteurs et rédacteurs listés dans la documentation de pandas dans les outils IO (texte, CSV, HDF5, …).pandas on Snowflake: Can read and write from Snowflake tables and read local or staged CSV, JSON, or Parquet files. For more information, see IO (lecture et écriture).
Types de données¶
pandas: possède un riche ensemble de types de données, tels que les entiers, les flottants, les chaînes, les typesdatetimeet les types catégoriels. Prend également en charge les types de données définis par l’utilisateur. Les types de données dans pandas sont généralement dérivés des données sous-jacentes et sont appliqués de manière stricte.pandas on Snowflake: Is constrained by Snowflake type system, which maps pandas objects to SQL by translating the pandas data types to the SQL types in Snowflake. A majority of pandas types have a natural equivalent in Snowflake, but the mapping is not always one to one. In some cases, multiple pandas types are mapped to the same SQL type.
Le tableau suivant liste les mappages de types entre pandas et Snowflake SQL :
type pandas |
Type Snowflake |
|---|---|
Tous les types d’entiers signés/non signés, y compris les types d’entiers étendus pandas |
NUMBER(38, 0) |
Tous les types de flottants, y compris les types de données flottants étendus de pandas |
FLOAT |
|
BOOLEAN |
|
STRING |
|
TIME |
|
DATE |
Tous les types de |
TIMESTAMP_NTZ |
Tous les types de |
TIMESTAMP_TZ |
|
ARRAY |
|
MAP |
Colonne d’objets avec des types de données mixtes |
VARIANT |
Timedelta64[ns] |
NUMBER(38, 0) |
Note
Les types de données suivants ne sont pas pris en charge : données catégorielles, données de période, données d’intervalle, données éparses et données définies par l’utilisateur. Timedelta n’est actuellement pris en charge que sur le client pandas de Snowpark. Lors de la réécriture de Timedelta dans Snowflake, il sera stocké sous forme de type Nombre.
Le tableau suivant fournit le mappage des types SQL de Snowflake vers les types de pandas on Snowflake à l’aide de df.dtypes :
Type Snowflake |
type pandas on Snowflake ( |
|---|---|
NUMBER ( |
|
NUMBER ( |
|
BOOLEAN |
|
STRING, TEXT |
|
VARIANT, BINARY, GEOMETRY, GEOGRAPHY |
|
ARRAY |
|
OBJECT |
|
TIME |
|
TIMESTAMP, TIMESTAMP_NTZ, TIMESTAMP_LTZ, TIMESTAMP_TZ |
|
DATE |
|
When you convert from the Snowpark pandas DataFrame to the native pandas DataFrame with to_pandas(), the native pandas DataFrame will
have refined data types compared to the pandas on Snowflake types, which are compatible with the Mappages des types de données SQL-Python for
functions and procedures.
Casting et inférence de type¶
pandas: s’appuie sur NumPy et suit par défaut le système de type NumPy et Python pour le casting implicite des types et l’inférence. Par exemple, il traite les booléens comme des types entiers, de sorte que1 + Truerenvoie2.pandas on Snowflake: mappe NumPy et les types Python en types Snowflake selon le tableau précédent, et utilise le système de types Snowflake sous-jacent pour le casting implicite des types et l’inférence. Par exemple, conformément à Types de données logiques, il ne convertit pas implicitement les booléens en types entiers, de sorte que1 + Trueentraîne une erreur de conversion de type.
Traitement des valeurs nulles¶
pandas: dans les versions 1.x de pandas, pandas était flexible lorsqu’il traitait les données manquantes, il traitait donc toutes les valeurs manquantes PythonNone,np.nan,pd.NaN,pd.NA, etpd.NaTcomme des valeurs manquantes. Dans les versions ultérieures de pandas (2.2.x), ces valeurs sont traitées comme des valeurs différentes.pandas on Snowflake: adopte une approche similaire aux versions antérieures de pandas qui traite toutes les valeurs précédentes de la liste comme des valeurs manquantes. Snowpark réutiliseNaN,NA, etNaTde pandas. Mais notez que toutes ces valeurs manquantes sont traitées de manière interchangeable et stockées en tant que valeurs SQL NULL dans la table Snowflake.
Alias de décalage/fréquence¶
pandas: les décalages de date dans pandas ont été modifiés dans la version 2.2.1. Les alias à une lettre'M','Q','Y', et autres ont été abandonnés au profit de décalages à deux lettres.pandas on Snowflake: utilise exclusivement les nouveaux décalages décrits dans la documentation sur les séries temporelles pandas.
Install the pandas on Snowflake library¶
Conditions préalables
Les versions de paquet suivantes sont nécessaires :
Python 3.9 (obsolète), 3.10, 3.11, 3.12 ou 3.13
Modin version 0.32.0
version pandas 2.2.*
Astuce
Pour utiliser pandas on Snowflake dans Snowflake Notebooks, voir les instructions d’installation dans Pandas on Snowflake dans des notebooks.
To install pandas on Snowflake in your development environment, follow these steps:
Allez dans le répertoire de votre projet et activez votre environnement virtuel Python.
Note
The API is under active development, so we recommend installing it in a Python virtual environment instead of system-wide. This practice allows each project you create to use a specific version, which insulates you from changes in future versions.
You can create a Python virtual environment for a particular Python version by using tools like Anaconda, Miniconda, or virtualenv.
For example, to use conda to create a Python 3.12 virtual environment, run these commands:
conda create --name snowpark_pandas python=3.12 conda activate snowpark_pandas
Note
If you previously installed an older version of pandas on Snowflake using Python 3.9 and pandas 1.5.3, you will need to upgrade your Python and pandas versions as described above. Follow the steps to create a new environment with Python 3.10 to 3.13.
Install the Snowpark Python library with Modin:
pip install "snowflake-snowpark-python[modin]"
ou
conda install snowflake-snowpark-python modin==0.28.1
Note
Confirm that
snowflake-snowpark-pythonversion 1.17.0 or later is installed.
Authentification à Snowflake¶
Before using pandas on Snowflake, you must establish a session with the Snowflake database. You can use a config file to choose the connection parameters for your session, or you can enumerate them in your code. For more information, see Creating a Session for Snowpark Python. If a unique active Snowpark Python session exists, pandas on Snowflake will automatically use it. For example:
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')
The pd.session is a Snowpark session, so you can do anything with it that you can do with any other Snowpark session. For example, you can use it to execute an arbitrary SQL query,
which results in a Snowpark DataFrame as per the Session API, but note that
the result is a Snowpark DataFrame, not a Snowpark pandas DataFrame.
# 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()
Alternatively, you can configure your Snowpark connection parameters in a configuration file. This eliminates the need to enumerate connection parameters in your code, which allows you to write your pandas on Snowflake code almost as you would normally write pandas code.
Create a configuration file located at
~/.snowflake/connections.tomlthat looks something like this:default_connection_name = "default" [default] account = "<myaccount>" user = "<myuser>" password = "<mypassword>" role="<myrole>" database = "<mydatabase>" schema = "<myschema>" warehouse = "<mywarehouse>"
To create a session using these credentials, use
snowflake.snowpark.Session.builder.create():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]])
You can also create multiple Snowpark sessions, then assign one of them to pandas on Snowflake. pandas on Snowflake only uses one session, so you have to explicitly assign one
of the sessions to pandas on Snowflake with pd.session = pandas_session:
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])
The following example shows that trying to use pandas on Snowflake when there is no active Snowpark session will raise a SnowparkSessionException with an
error like « pandas on Snowflake requires an active snowpark session, but there is none. » After you create a session, you can use pandas on Snowflake. For example:
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
df = pd.DataFrame([1, 2, 3])
L’exemple suivant montre qu’en essayant d’utiliser pandas on Snowflake lorsqu’il y a plusieurs sessions Snowpark actives, vous obtiendrez SnowparkSessionException avec un message du type « Il y a plusieurs sessions snowpark actives, mais vous devez en choisir une pour pandas on Snowflake. »
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])
Note
You must set the session used for a new pandas on Snowflake DataFrame or Series via modin.pandas.session.
However, joining or merging DataFrames created with different sessions is not supported, so you should avoid repeatedly setting different sessions
and creating DataFrames with different sessions in a workflow.
API reference¶
Voir la référence d’API pandas on Snowflake pour une liste complète des APIs et des méthodes mises en œuvre actuellement disponibles.
Pour une liste complète des opérations prises en charge, consultez les tableaux suivants dans la référence de pandas on Snowflake :
APIs DataFrame prises en charge
APIs GroupBy prises en charge
APIs DatetimeProperties prises en charge
APIs StringMethods prises en charge
APIs et paramètre de configuration pour l’exécution hybride¶
L’exécution hybride utilise une combinaison de l’estimation de la taille de l’ensemble de données et des opérations appliquées au DataFrame pour déterminer le choix du backend. En général, les ensembles de données de moins de 100 000 lignes auront tendance à utiliser des pandas locaux. Ceux de plus de 100 000 lignes auront tendance à utiliser Snowflake, à moins que l’ensemble de données ne soit chargé à partir de fichiers locaux.
Configuration des coûts de transfert¶
Pour remplacer le seuil de basculement par défaut par une autre valeur de limite de lignes, vous pouvez modifier la variable d’environnement avant d’initialiser un DataFrame :
# Change row transfer threshold to 500k
from modin.config.envvars import SnowflakePandasTransferThreshold
SnowflakePandasTransferThreshold.put(500_000)
La définition de cette valeur pénalisera le transfert de lignes hors de Snowflake.
Configuration des limites d’exécution locale¶
Une fois qu’un DataFrame est local, il restera généralement local à moins qu’il ne soit nécessaire de le ramener à Snowflake pour une fusion, mais il existe une limite supérieure prise en compte pour la taille maximale des données pouvant être traitées localement. Actuellement, cette limite est de 10 millions de lignes.
Vérification et définition du backend¶
Pour vérifier le backend actuel du choix, vous pouvez utiliser la commande df.getbackend(), qui renvoie Pandas pour une exécution locale, ou Snowflake pour l’exécution du pushdown.
Pour définir le backend actuel du choix avec set_backend ou son alias move_to :
df_local = df.set_backend('Pandas')
df_local = df.move_to('Pandas')
df_snow = df.set_backend('Snowflake')
Vous pouvez également définir le backend en place :
df.set_backend('Pandas', inplace=True)
Pour inspecter et afficher des informations sur la raison pour laquelle les données ont été déplacées :
pd.explain_switch()
Remplacer manuellement la sélection du backend par l’épinglage du backend¶
Par défaut, Snowflake choisit automatiquement le meilleur backend pour un DataFrame et une opération donnés. Si vous souhaitez remplacer la sélection automatique des moteurs, vous pouvez désactiver le basculement automatique sur un objet et toutes les données résultantes produites par celui-ci, en utilisant la méthode pin_backend() :
pinned_df_snow = df.move_to('Snowflake').pin_backend()
To re-enable automatic backend switching, call unpin_backend():
unpinned_df_snow = pinned_df_snow.unpin_backend()
Utilisation des pandas Snowpark dans les Notebooks Snowflake¶
Pour utiliser pandas on Snowflake dans les Notebooks Snowflake, voir pandas on Snowflake dans les Notebooks.
Utilisation des pandas Snowpark dans les feuilles de calcul Python¶
Pour utiliser les pandas Snowpark, vous devez installer Modin en sélectionnant modin à partir de Packages dans l’environnement de feuille de calcul Python.
Vous pouvez sélectionner le type de retour de la fonction Python sous Settings > Return type. Par défaut, il est défini sur une table Snowpark. Pour afficher le DataFrame pandas Snowpark comme résultat, vous pouvez convertir un DataFrame pandas Snowpark en DataFrame Snowpark en appelant to_snowpark(). Aucun coût d’E/S ne sera encouru lors de cette conversion.
Voici un exemple d’utilisation des pandas Snowpark avec les feuilles de calcul Python :
import snowflake.snowpark as snowpark
def main(session: snowpark.Session):
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
[1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
[1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
columns=["DAY", "LOCATION", "SNOWFALL"])
# Print a sample of the dataframe to standard output.
print(df)
snowpark_df = df.to_snowpark(index=None)
# Return value will appear in the Results tab.
return snowpark_df
Utilisation de pandas on Snowflake dans les procédures stockées¶
Vous pouvez utiliser pandas on Snowflake dans une procédure stockée pour créer un pipeline de données et planifier l’exécution de la procédure stockée avec des tâches.
Voici comment vous pouvez créer une procédure stockée à l’aide de SQL :
CREATE OR REPLACE PROCEDURE run_data_transformation_pipeline_sp()
RETURNS VARCHAR
LANGUAGE PYTHON
RUNTIME_VERSION = 3.12
PACKAGES = ('snowflake-snowpark-python','modin')
HANDLER='data_transformation_pipeline'
AS $$
def data_transformation_pipeline(session):
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from datetime import datetime
# Create a Snowpark pandas DataFrame with sample data.
df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
[1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
[1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
columns=["DAY", "LOCATION", "SNOWFALL"])
# Drop rows with null values.
df = df.dropna()
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2
# Save Results as a Snowflake Table
timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M")
save_path = f"OUTPUT_{timestamp}"
df.to_snowflake(name=save_path, if_exists="replace", index=False)
return f'Transformed DataFrame saved to {save_path}.'
$$;
Voici comment vous pouvez créer une procédure stockée à l’aide de l’API Snowflake Python :
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'])
Pour appeler la procédure stockée, vous pouvez exécuter dt_pipeline_sproc() en Python ou CALL run_data_transformation_pipeline_sp() en SQL.
Utilisation de pandas on Snowflake avec des bibliothèques tierces¶
Pandas est couramment utilisé avec les APIs de la bibliothèque tierce pour les applications de visualisation et de machine learning. pandas on Snowflake est interopérable avec la plupart de ces bibliothèques, de sorte qu’elles peuvent être utilisées sans être converties explicitement en DataFrames Pandas. Notez toutefois que l’exécution distribuée n’est pas souvent prise en charge dans la plupart des bibliothèques tierces, sauf dans des cas d’utilisation limités. Par conséquent, cela peut conduire à des performances plus lentes sur les grands ensembles de données.
Bibliothèques tierces prises en charge¶
Les bibliothèques listées ci-dessous acceptent en entrée les DataFrames pandas on Snowflake, mais toutes leurs méthodes n’ont pas été testées. Pour un statut d’interopérabilité approfondi au niveau de l’API, voir Interopérabilité avec des bibliothèques tierces.
Plotly
Altair
Seaborn
Matplotlib
Numpy
Scikit-learn
XGBoost
NLTK
Streamlit
pandas on Snowflake a actuellement une compatibilité limitée pour certaines APIs NumPy et Matplotlib, comme une implémentation distribuée pour np.where et l’interopérabilité avec df.plot. En convertissant des DataFrames pandas Snowpark via to_pandas() lorsque vous travaillez avec ces bibliothèques tierces, vous éviterez plusieurs appels d’E/S.
Voici un exemple avec Altaïr pour la visualisation et scikit-learn pour le machine learning.
# Create a Snowpark session with a default connection.
session = Session.builder.create()
train = pd.read_snowflake('TITANIC')
train[['Pclass', 'Parch', 'Sex', 'Survived']].head()
Pclass Parch Sex Survived
0 3 0 male 0
1 1 0 female 1
2 3 0 female 1
3 1 0 female 1
4 3 0 male 0
import altair as alt
survived_per_age_plot = alt.Chart(train).mark_bar(
).encode(
x=alt.X('Age', bin=alt.Bin(maxbins=25)),
y='count()',
column='Survived:N',
color='Survived:N',
).properties(
width=300,
height=300
).configure_axis(
grid=False
)
Vous pouvez également analyser le taux de survie en fonction du sexe.
# Perform groupby aggregation with Snowpark pandas
survived_per_gender = train.groupby(['Sex','Survived']).agg(count_survived=('Survived', 'count')).reset_index()
survived_per_gender_pandas = survived_per_gender
survived_per_gender_plot = alt.Chart(survived_per_gender).mark_bar().encode(
x='Survived:N',
y='Survived_Count',
color='Sex',
column='Sex'
).properties(
width=200,
height=200
).configure_axis(
grid=False
)
You can now use scikit-learn to train a simple model.
feature_cols = ['Pclass', 'Parch']
X_pandas = train.loc[:, feature_cols]
y_pandas = train["Survived"]
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_pandas, y_pandas)
y_pred_pandas = logreg.predict(X_pandas)
acc_eval = accuracy_score(y_pandas, y_pred_pandas)
Note
Pour plus de performance, nous vous recommandons une conversion en DataFrames pandas via to_pandas(), en particulier lorsque vous utilisez des bibliothèques de machine learning telles que scikit-learn. Cependant, la fonction to_pandas() collecte toutes les lignes. Il peut donc être préférable de réduire d’abord la taille du dataframe à l’aide de sample(frac=0.1) ou head(10).
Bibliothèques non prises en charge¶
Lorsque vous utilisez des bibliothèques tierces non prises en charge avec un DataFrame pandas on Snowflake, nous vous recommandons de convertir le DataFrame pandas on Snowflake DataFrame pandas en appelant to_pandas() avant de transmettre le DataFrame à la méthode de la bibliothèque tierce.
Note
L’appel de to_pandas() extrait vos données de Snowflake et les place en mémoire, alors gardez cela à l’esprit pour les grands ensembles de données et les cas d’utilisation sensibles.
Utilisation des fonctions Snowflake Cortex LLM avec Snowpark pandas¶
Vous pouvez utiliser les fonctions Snowflake Cortex LLM via la fonction Snowpark pandas.
Vous appliquez la fonction avec des arguments de mot-clé spéciaux. Actuellement, les fonctions Cortex suivantes sont prises en charge :
L’exemple suivant utilise la fonction TRANSLATE sur plusieurs enregistrements dans un DataFrame Snowpark pandas :
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.cortex import Translate
content_df = pd.DataFrame(["good morning","hello", "goodbye"], columns=["content"])
result = content_df.apply(Translate, from_language="en", to_language="de")
result["content"]
Sortie :
Guten Morgen
Hallo
Auf Wiedersehen
Name: content, dtype: object
L’exemple suivant utilise la fonction SENTIMENT (SNOWFLAKE.CORTEX) sur une table Snowflake nommée reviews :
from snowflake.cortex import Sentiment
s = pd.read_snowflake("reviews")["content"]
result = s.apply(Sentiment)
result
L’exemple suivant utilise EXTRACT_ANSWER (SNOWFLAKE.CORTEX) pour répondre à une question :
from snowflake.cortex import ExtractAnswer
content = "The Snowflake company was co-founded by Thierry Cruanes, Marcin Zukowski, and Benoit Dageville in 2012 and is headquartered in Bozeman, Montana."
df = pd.DataFrame([content])
result = df.apply(ExtractAnswer, question="When was Snowflake founded?")
result[0][0][0]["answer"]
Sortie :
'2012'
Note
Le paquet snowflake-ml-python doit être installé pour utiliser les fonctions Cortex LLM.
Limitations¶
pandas on Snowflake présente les limitations suivantes :
pandas on Snowflake n’offre aucune garantie de compatibilité avec les bibliothèques tierces OSS. À partir de la version 1.14.0a1, cependant, Snowpark pandas introduit une compatibilité limitée pour NumPy, en particulier pour l’utilisation de
np.where. Pour plus d’informations, voir Intéropérabilité de NumPy.When you call third-party library APIs with a Snowpark pandas DataFrame, Snowflake recommends that you convert the Snowpark pandas DataFrame to a pandas DataFrame by calling
to_pandas()before passing the DataFrame to the third-party library call. For more information, see Utilisation de pandas on Snowflake avec des bibliothèques tierces.pandas on Snowflake is not integrated with Snowpark ML. When you use Snowpark ML, we recommend that you convert the Snowpark pandas DataFrame to a Snowpark DataFrame using to_snowpark() before calling Snowpark ML.
Les objets
MultiIndexparesseux ne sont pas pris en charge. LorsqueMultiIndexest utilisé, il renvoie un objetMultiIndexpandas natif, ce qui nécessite d’extraire toutes les données du côté client.Not all pandas APIs have a distributed implementation in pandas on Snowflake, although some are being added. For unsupported APIs,
NotImplementedErroris thrown. For information about supported APIs, see the API reference documentation.pandas on Snowflake assure la compatibilité avec n’importe quelle version patch de pandas 2.2.
Snowpark pandas cannot be referenced within Snowpark pandas
applyfunction. You can only use native pandas insideapply.Voici un exemple :
import modin.pandas as pd import pandas df.apply(lambda row: pandas.to_datetime(f"{row.date} {row.time}"), axis=1)
Résolution des problèmes¶
This section describes troubleshooting tips for using pandas on Snowflake.
When troubleshooting, try running the same operation on a native pandas DataFrame (or a sample) to see whether the same error persists. This approach might provide hints on how to fix your query. For example:
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()
If you have a long-running notebook opened, note that by default Snowflake sessions time out after the session is idle for 240 minutes (4 hours). When the session expires, if you run additional pandas on Snowflake queries, the following message appears: « Authentication token has expired. The user must authenticate again. » At this point, you must re-establish the connection to Snowflake. This might cause the loss of any unpersisted session variables. For more information about how to configure the session idle timeout parameter, see Session policies.
Meilleures pratiques¶
Cette section décrit les meilleures pratiques à suivre lors de l’utilisation de pandas on Snowflake.
Avoid using iterative code patterns, such as
forloops,iterrows, anditeritems. Iterative code patterns quickly increase the generated query complexity. Let pandas on Snowflake, not the client code, perform the data distribution and computation parallelization. With regard to iterative code patterns, look for operations that can be performed on the whole DataFrame, and use the corresponding operations instead.
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)],
},
)
Avoid calling
apply,applymap, andtransform, which are eventually implemented with UDFs or UDTFs, which might not be as performant as regular SQL queries. If the function applied has an equivalent DataFrame or series operation, use that operation instead. For example, instead ofdf.groupby('col1').apply('sum'), directly calldf.groupby('col1').sum().Appelez
to_pandas()avant de passer le DataFrame ou une série vers un appel de bibliothèque tierce. pandas on Snowflake ne fournit pas de garantie de compatibilité avec les bibliothèques tierces.Use a materialized regular Snowflake table to avoid extra I/O overhead. pandas on Snowflake works on top of a data snapshot that only works for regular tables. For other types, including external tables, views, and Apache Iceberg™ tables, a temporary table is created before the snapshot is taken, which introduces extra materialization overhead.
pandas on Snowflake fournit une capacité de clonage rapide et sans copie lors de la création de DataFrames à partir de tables de Snowflake avec
read_snowflake.Vérifiez deux fois le type de résultat avant de procéder à d’autres opérations, et effectuez un casting de type explicite à l’aide de
astypesi nécessaire.En raison de la capacité limitée d’inférence de type, si aucune indication de type n’est donnée,
df.applyrenverra des résultats de type objet (variante) même si le résultat contient toutes les valeurs entières. Si d’autres opérations nécessitent que la colonnedtypesoitint, vous pouvez procéder à un casting de type explicite en appelant la méthodeastypepour corriger le type de la colonne avant de continuer.Avoid calling APIs that require evaluation and materialization unless necessary.
Les APIs qui ne renvoient pas
SeriesouDataframenécessitent une évaluation exigeante et une matérialisation pour produire le résultat dans le bon type. Il en va de même pour les méthodes de traçage. Réduisez les appels vers les APIs afin de réduire les évaluations et la matérialisation inutiles.Évitez d’appeler
np.where(<cond>, <scalar>, n)sur les grands ensembles de données.<scalar >sera diffusé à un DataFrame de la taille de<cond>, ce qui peut être lent.Lorsque vous travaillez avec des requêtes construites de manière itérative,
df.cache_resultpeut être utilisé pour matérialiser des résultats intermédiaires afin de réduire l’évaluation répétée et d’améliorer la latence et de réduire la complexité de la requête globale. Par exemple :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)
In the example above, the query to produce
df2is expensive to compute and is reused in the creation of bothdf3anddf4. Materializingdf2into a temporary table (making subsequent operations involvingdf2a table scan instead of a pivot) can reduce the overall latency of the code block: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)
Exemples¶
Voici un exemple de code avec des opérations pandas. Nous commençons par un DataFrame pandas Snowpark nommé pandas_test, qui contient trois colonnes : COL_STR, COL_FLOAT, et COL_INT. Pour voir le notebook associé à ces exemples, consultez les exemples de pandas on Snowflake dans le référentiel Snowflake-Labs.
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
from snowflake.snowpark import Session
CONNECTION_PARAMETERS = {
'account': '<myaccount>',
'user': '<myuser>',
'password': '<mypassword>',
'role': '<myrole>',
'database': '<mydatabase>',
'schema': '<myschema>',
'warehouse': '<mywarehouse>',
}
session = Session.builder.configs(CONNECTION_PARAMETERS).create()
df = pd.DataFrame([['a', 2.1, 1],['b', 4.2, 2],['c', 6.3, None]], columns=["COL_STR", "COL_FLOAT", "COL_INT"])
df
COL_STR COL_FLOAT COL_INT
0 a 2.1 1.0
1 b 4.2 2.0
2 c 6.3 NaN
We save the DataFrame as a Snowflake table named pandas_test, which we will use throughout our examples.
df.to_snowflake("pandas_test", if_exists='replace',index=False)
Ensuite, nous créons un DataFrame à partir de la table Snowflake. Nous supprimons la colonne COL_INT et sauvegardons le résultat dans Snowflake avec une colonne nommée row_position.
# Create a DataFrame out of a Snowflake table.
df = pd.read_snowflake('pandas_test')
df.shape
(3, 3)
df.head(2)
COL_STR COL_FLOAT COL_INT
0 a 2.1 1
1 b 4.2 2
df.dropna(subset=["COL_FLOAT"], inplace=True)
df
COL_STR COL_FLOAT COL_INT
0 a 2.1 1
1 c 6.3 2
df.shape
(2, 3)
df.dtypes
COL_STR object
COL_FLOAT float64
COL_INT int64
dtype: object
# Save the result back to Snowflake with a row_pos column.
df.reset_index(drop=True).to_snowflake('pandas_test2', if_exists='replace', index=True, index_label=['row_pos'])
The result is a new table, pandas_test2, which looks like this:
row_pos COL_STR COL_FLOAT COL_INT
0 1 a 2.0 1
1 2 b 4.0 2
IO (lecture et écriture)¶
# 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')
Pour plus d’informations, voir Entrée/sortie.
Indexation¶
df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "z"]})
df.columns
Index(['a', 'b'], dtype='object')
df.index
Index([0, 1, 2], dtype='int8')
df["a"]
0 1
1 2
2 3
Name: a, dtype: int8
df["b"]
0 x
1 y
2 z
Name: b, dtype: object
df.iloc[0,1]
'x'
df.loc[df["a"] > 2]
a b
2 3 z
df.columns = ["c", "d"]
df
c d
0 1 x
1 2 y
2 3 z
df = df.set_index("c")
df
d
c
1 x
2 y
3 z
df.rename(columns={"d": "renamed"})
renamed
c
1 x
2 y
3 z
Valeurs manquantes¶
import numpy as np
df = pd.DataFrame([[np.nan, 2, np.nan, 0],
[3, 4, np.nan, 1],
[np.nan, np.nan, np.nan, np.nan],
[np.nan, 3, np.nan, 4]],
columns=list("ABCD"))
df
A B C D
0 NaN 2.0 NaN 0.0
1 3.0 4.0 NaN 1.0
2 NaN NaN NaN NaN
3 NaN 3.0 NaN 4.0
df.isna()
A B C D
0 True False True False
1 False False True False
2 True True True True
3 True False True False
df.fillna(0)
A B C D
0 0.0 2.0 0.0 0.0
1 3.0 4.0 0.0 1.0
2 0.0 0.0 0.0 0.0
3 0.0 3.0 0.0 4.0
df.dropna(how="all")
A B C D
0 NaN 2.0 NaN 0.0
1 3.0 4.0 NaN 1.0
3 NaN 3.0 NaN 4.0
Type de conversion¶
df = pd.DataFrame({"int": [1,2,3], "str": ["4", "5", "6"]})
df
int str
0 1 4
1 2 5
2 3 6
df_float = df.astype(float)
df_float
int str
0 1.0 4.0
1 2.0 5.0
2 3.0 6.0
df_float.dtypes
int float64
str float64
dtype: object
pd.to_numeric(df.str)
0 4.0
1 5.0
2 6.0
Name: str, dtype: float64
df = pd.DataFrame({'year': [2015, 2016],
'month': [2, 3],
'day': [4, 5]})
pd.to_datetime(df)
0 2015-02-04
1 2016-03-05
dtype: datetime64[ns]
Opérations binaires¶
df_1 = pd.DataFrame([[1,2,3],[4,5,6]])
df_2 = pd.DataFrame([[6,7,8]])
df_1.add(df_2)
0 1 2
0 7.0 9.0 11.0
1 NaN NaN NaN
s1 = pd.Series([1, 2, 3])
s2 = pd.Series([2, 2, 2])
s1 + s2
0 3
1 4
2 5
dtype: int64
df = pd.DataFrame({"A": [1,2,3], "B": [4,5,6]})
df["A+B"] = df["A"] + df["B"]
df
A B A+B
0 1 4 5
1 2 5 7
2 3 6 9
Agrégation¶
df = pd.DataFrame([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[np.nan, np.nan, np.nan]],
columns=['A', 'B', 'C'])
df.agg(['sum', 'min'])
A B C
sum 12.0 15.0 18.0
min 1.0 2.0 3.0
df.median()
A 4.0
B 5.0
C 6.0
dtype: float64
Fusionner¶
df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo'],
'value': [1, 2, 3, 5]})
df1
lkey value
0 foo 1
1 bar 2
2 baz 3
3 foo 5
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo'],
'value': [5, 6, 7, 8]})
df2
rkey value
0 foo 5
1 bar 6
2 baz 7
3 foo 8
df1.merge(df2, left_on='lkey', right_on='rkey')
lkey value_x rkey value_y
0 foo 1 foo 5
1 foo 1 foo 8
2 bar 2 bar 6
3 baz 3 baz 7
4 foo 5 foo 5
5 foo 5 foo 8
df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']})
df
key A
0 K0 A0
1 K1 A1
2 K2 A2
3 K3 A3
4 K4 A4
5 K5 A5
other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],
'B': ['B0', 'B1', 'B2']})
df.join(other, lsuffix='_caller', rsuffix='_other')
key_caller A key_other B
0 K0 A0 K0 B0
1 K1 A1 K1 B1
2 K2 A2 K2 B2
3 K3 A3 None None
4 K4 A4 None None
5 K5 A5 None None
Groupby¶
df = pd.DataFrame({'Animal': ['Falcon', 'Falcon','Parrot', 'Parrot'],
'Max Speed': [380., 370., 24., 26.]})
df
Animal Max Speed
0 Falcon 380.0
1 Falcon 370.0
2 Parrot 24.0
3 Parrot 26.0
df.groupby(['Animal']).mean()
Max Speed
Animal
Falcon 375.0
Parrot 25.0
Pour plus d’informations, voir GroupBy.
Pivot¶
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"C": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
"E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
df
A B C D E
0 foo one small 1 2
1 foo one large 2 4
2 foo one large 2 5
3 foo two small 3 5
4 foo two small 3 6
5 bar one large 4 6
6 bar one small 5 8
7 bar two small 6 9
8 bar two large 7 9
pd.pivot_table(df, values='D', index=['A', 'B'],
columns=['C'], aggfunc="sum")
C large small
A B
bar one 4.0 5
two 7.0 6
foo one 4.0 1
two NaN 6
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
'baz': [1, 2, 3, 4, 5, 6],
'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
df
foo bar baz zoo
0 one A 1 x
1 one B 2 y
2 one C 3 z
3 two A 4 q
4 two B 5 w
5 two C 6 t