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.

O pandas on Snowflake determina de forma inteligente se o código pandas deve ser executado localmente ou se deve-se usar o mecanismo Snowflake para dimensionar e melhorar o desempenho por meio de Execução híbrida. Ao trabalhar com grandes conjuntos de dados no Snowpark, ele executa cargas de trabalho nativamente no Snowflake por meio de transpilação para SQL, permitindo o aproveitamento da paralelização e os benefícios de governança e segurança de dados do Snowflake.

O pandas on Snowflake é fornecido pela API Snowpark pandas como parte da biblioteca Snowpark Python, que permite o processamento de dados escaláveis do código Python dentro da plataforma Snowflake.

Benefícios do uso 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.

Como começar com o pandas on Snowflake

Nota

Para um exemplo prático de como usar pandas on Snowflake, verifique este Notebook e veja isto Vídeo.

Para instalar o pandas on Snowflake, é possível usar conda ou pip para instalar o pacote. Para obter instruções detalhadas, consulte Instalação.

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

Depois que o pandas on Snowflake estiver instalado, em vez de importar o pandas como import pandas as pd, use as duas linhas a seguir:

import modin.pandas as pd
import snowflake.snowpark.modin.plugin
Copy

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
Copy
      DAY  LOCATION  SNOWFALL
0       1  Big Bear       8.0
1       2  Big Bear      10.0
2       3  Big Bear       NaN
3       1     Tahoe       3.0
4       2     Tahoe       NaN
5       3     Tahoe      13.0
6       1  Whistler       NaN
7  Friday  Whistler      40.0
8       3  Whistler      25.0
# In-place point update to fix data error.
df.loc[df["DAY"]=="Friday","DAY"]=2

# Inspect the columns after update.
# Note how the data type is updated automatically after transformation.
df["DAY"]
Copy
0    1
1    2
2    3
3    1
4    2
5    3
6    1
7    2
8    3
Name: DAY, dtype: int64
# Drop rows with null values.
df.dropna()
Copy
  DAY  LOCATION  SNOWFALL
0   1  Big Bear       8.0
1   2  Big Bear      10.0
3   1     Tahoe       3.0
5   3     Tahoe      13.0
7   2  Whistler      40.0
8   3  Whistler      25.0
# Compute the average daily snowfall across locations.
df.groupby("LOCATION").mean()["SNOWFALL"]
Copy
LOCATION
Big Bear     9.0
Tahoe        8.0
Whistler    32.5
Name: SNOWFALL, dtype: float64

read_snowflake oferece suporte à leitura de exibições Snowflake, tabelas dinâmicas, tabelas Iceberg e muito mais. Você também pode passar um SQL consulte diretamente e receba de volta um pandas on Snowflake DataFrame, facilitando a movimentação contínua entre SQL e pandas on Snowflake.

summary_df = pd.read_snowflake("SELECT LOCATION, AVG(SNOWFALL) AS avg_snowfall FROM SNOWFALL GROUP BY LOCATION")
summary_df
Copy

Como funciona a execução híbrida

Nota

Começando pela versão Snowpark Python 1.40.0, a execução híbrida é habilitada por padrão ao usar pandas on Snowflake.

O pandas on Snowflake usa execução híbrida para determinar se o código pandas deve ser executado localmente ou se deve-se usar o mecanismo Snowflake para dimensionar e aprimorar o desempenho. Isso permite que você continue escrevendo código pandas familiar para desenvolver pipelines robustos, sem ter que pensar na maneira mais ideal e eficiente de executar seu código, enquanto se beneficia perfeitamente do desempenho e da escalabilidade do Snowflake à medida que seus pipelines são dimensionados.

execução híbrida

Exemplo 1: Crie uma pequena de 11 linhas DataFrame em linha. Com a execução híbrida, o Snowflake seleciona o backend pandas local e na memória para executar a operação:

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

Exemplo 2: Como criar uma tabela com 10 milhões de linhas de transações

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

Você pode ver que a tabela usa o Snowflake como backend, pois esta é uma tabela grande que reside no 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"]
Copy

Exemplo 3: Filtragem de dados e execução de um groupby agregação resultando em 7 linhas de dados.

Quando os dados são filtrados, o Snowflake reconhece implicitamente a escolha de backend das alterações do mecanismo de Snowflake para pandas, já que a saída tem apenas 7 linhas de dados.

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

Notes and limitations

  • O tipo DataFrame sempre será modin.pandas.DataFrame/Series/etc mesmo quando o backend muda, para garantir a interoperabilidade/compatibilidade com o código downstream.

  • Para determinar qual backend usar, o Snowflake às vezes usa uma estimativa do tamanho da linha em vez de calcular o comprimento exato do DataFrame em cada etapa. Isso significa que o Snowflake pode nem sempre mudar para o back-end ideal imediatamente após uma operação quando o conjunto de dados fica maior/menor (por exemplo, filtro, agregação).

  • Quando há uma operação que combina duas ou mais DataFrames em diferentes backends, o Snowflake determina para onde mover os dados com base no menor custo de transferência de dados.

  • As operações de filtragem podem não resultar na movimentação de dados, porque o Snowflake pode não ser capaz de estimar o tamanho dos dados filtrados subjacentes.

  • Qualquer DataFrames composos de dados Python na memória usará o backend pandas, como o seguinte:

    pd.DataFrame([1])
    
    Copy
    pd.DataFrame(pandas.DataFrame([1]))
    
    Copy
    pd.Series({'a': [4]})
    
    Copy
    An empty DataFrame: pd.DataFrame()
    
    Copy
  • DataFrames passará automaticamente do mecanismo Snowflake para o mecanismo pandas em um conjunto limitado de operações. Essas operações incluem df.apply, df.plot, df.iterrows, df.itertuples, series.items, e em operações de redução em que o tamanho dos dados é garantido ser menor. Nem todas as operações são pontos suportados onde a migração de dados pode ocorrer.

  • A execução híbrida não move automaticamente uma DataFrame do pandas Engine de volta para o Snowflake, exceto nos casos em que uma operação como pd.concat atua em vários DataFrames.

  • O Snowflake não move automaticamente um DataFrame do pandas Engine de volta para o Snowflake, a menos que uma operação como pd.concat atua em vários DataFrames.

When you should use pandas on Snowflake

Você deve usar pandas on Snowflake se alguma das seguintes condições for verdadeira:

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

Para obter mais informações, consulte DataFrames Snowpark vs. DataFrame Snowpark pandas: Qual devo escolher?

Como usar o pandas on Snowflake com Snowpark DataFrames

O pandas on Snowflake e DataFrame API é altamente interoperável, então você pode construir um pipeline que aproveite ambas as APIs. Para obter mais informações, consulte DataFrames Snowpark vs. DataFrame Snowpark pandas: Qual devo escolher?

Você pode usar as seguintes operações para fazer conversões entre Snowpark DataFrames e Snowpark pandas DataFrames:

Operação

Entrada

Saída

to_snowpark_pandas

Snowpark DataFrame

DataFrame Snowpark pandas

to_snowpark

DataFrame Snowpark pandas ou série Snowpark Pandas

Snowpark DataFrame

Como o pandas on Snowflake se compara ao pandas nativo

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:

Operação

Entrada

Saída

to_pandas

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.

pd.DataFrame(…)

pandas DataFrame nativo, dados brutos, objeto Snowpark pandas

DataFrame Snowpark pandas

Ambiente de execução

  • 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: fornece a mesma experiência de API que o pandas. Ele imita o modelo de avaliação adiantada do pandas, mas cria internamente um gráfico de consulta avaliado lentamente para permitir a otimização entre as operações.

    As operações de fusão e transpilação por meio de um gráfico de consulta permitem oportunidades adicionais de otimização para o mecanismo de computação distribuído subjacente do Snowflake, o que diminui o custo e o tempo de execução do pipeline de ponta a ponta em comparação à execução do pandas diretamente no Snowflake.

    Nota

    I/O-related APIs and APIs whose return value is not a Snowpark pandas object (that is, DataFrame, Series or Index) always evaluate eagerly. For example:

    • read_snowflake

    • to_snowflake

    • to_pandas

    • to_dict

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

Fonte e armazenamento de dados

Tipos de dados

  • pandas: possui um rico conjunto de tipos de dados, como inteiros, flutuantes, cadeias de caracteres, tipos datetime e tipos categóricos. Também oferece suporte a tipos de dados definidos pelo usuário. Os tipos de dados no pandas geralmente são derivados dos dados subjacentes e são aplicados de forma rigorosa.

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

A tabela a seguir lista os mapeamentos de tipos entre pandas e Snowflake SQL:

Tipo pandas

Tipo de dados Snowflake

Todos os tipos inteiros assinados/não assinados, incluindo tipos inteiros estendidos do pandas

NUMBER(38, 0)

Todos os tipos de float, incluindo os tipos de dados float estendidos do pandas

FLOAT

bool, BooleanDtype

BOOLEAN

str, StringDtype

STRING

datetime.time

TIME

datetime.date

DATE

Todos os tipos datetime sem fuso horário

TIMESTAMP_NTZ

Todos os tipos datetime com fuso horário

TIMESTAMP_TZ

list, tuple, array

ARRAY

dict, json

MAP

Coluna de objeto com tipos de dados mistos

VARIANT

Timedelta64[ns]

NUMBER(38, 0)

Nota

Tipos de dados categóricos, de período, de intervalo, esparsos e definidos pelo usuário não são suportados. Atualmente, o Timedelta só é compatível com o cliente pandas no Snowpark. Ao escrever Timedelta de volta no Snowflake, ele será armazenado como tipo Number.

A tabela a seguir fornece o mapeamento dos tipos SQL Snowflake de volta para os tipos pandas on Snowflake usando df.dtypes:

Tipo de dados Snowflake

Tipo pandas on Snowflake (df.dtypes)

NUMBER (scale = 0)

int64

NUMBER (scale > 0), REAL

float64

BOOLEAN

bool

STRING, TEXT

object (str)

VARIANT, BINARY, GEOMETRY, GEOGRAPHY

object

ARRAY

object (list)

OBJECT

object (dict)

TIME

object (datetime.time)

TIMESTAMP, TIMESTAMP_NTZ, TIMESTAMP_LTZ, TIMESTAMP_TZ

datetime64[ns]

DATE

object (datetime.date)

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 Mapeamentos de tipos de dados SQL-Python for functions and procedures.

Conversão e inferência de tipos

  • pandas: depende de NumPy e por padrão segue o NumPy e sistema de tipos Python para conversão de tipos implícita e inferência. Por exemplo, ele trata boolianos como tipos inteiros, então 1 + True retorna 2.

  • pandas on Snowflake: mapeia os tipos NumPy e Python para tipos Snowflake de acordo com a tabela anterior e usa o sistema de tipos Snowflake subjacente para conversão de tipos e inferência implícitos. Por exemplo, de acordo com Tipos de dados lógicos, ele não converte implicitamente boolianos em tipos inteiros, então 1 + True resulta em um erro de conversão de tipo.

Tratamento de valor nulo

  • pandas: nas versões 1.x do pandas, o pandas era flexível ao manipular dados ausentes, então tratou todo o Python None, np.nan, pd.NaN, pd.NA e pd.NaT como valores ausentes. Em versões posteriores do pandas (2.2.x), esses valores são tratados como valores diferentes.

  • pandas on Snowflake: adota uma abordagem semelhante às versões anteriores do pandas que trata todos os valores anteriores listados como valores ausentes. O Snowpark reutiliza NaN, NA e NaT do pandas. Mas observe que todos esses valores ausentes são tratados de forma intercambiável e armazenados como SQL NULL na tabela Snowflake.

Aliases de offset/frequência

  • pandas: os offsets de data no pandas foram alterados na versão 2.2.1. Os aliases de uma única letra 'M', 'Q', 'Y' e outros foram descontinuados em favor de offsets de duas letras.

  • pandas on Snowflake: usa exclusivamente os novos offsets descritos ao documentação da série temporal dos pandas.

Install the pandas on Snowflake library

Pré-requisitos

As seguintes versões do pacote são necessárias:

  • Python 3.9 (obsoleto), 3.10, 3.11, 3.12 ou 3.13

  • Modin version 0.32.0

  • pandas versão 2.2.*

Dica

Para usar pandas on Snowflake em Snowflake Notebooks, consulte as instruções de configuração em pandas on Snowflake no notebooks.

To install pandas on Snowflake in your development environment, follow these steps:

  1. Mude para o diretório do seu projeto e ative seu ambiente virtual Python.

    Nota

    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
    
    Copy

    Nota

    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.

  2. Install the Snowpark Python library with Modin:

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

    ou

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

Nota

Confirm that snowflake-snowpark-python version 1.17.0 or later is installed.

Autenticação no 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')
Copy

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

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.

  1. Create a configuration file located at ~/.snowflake/connections.toml that looks something like this:

    default_connection_name = "default"
    
    [default]
    account = "<myaccount>"
    user = "<myuser>"
    password = "<mypassword>"
    role="<myrole>"
    database = "<mydatabase>"
    schema = "<myschema>"
    warehouse = "<mywarehouse>"
    
    Copy
  2. 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]])
    
    Copy

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

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

O exemplo a seguir mostra que tentar usar pandas on Snowflake quando há várias sessões ativas do Snowpark causará SnowparkSessionException com uma mensagem como: “Há várias sessões ativas do Snowpark, mas é preciso escolher uma para 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])
Copy

Nota

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

Veja a referência da API pandas on Snowflake para obter a lista completa de APIs atualmente implementadas e métodos disponíveis.

Para obter uma lista completa de operações compatíveis, consulte as seguintes tabelas na referência do pandas on Snowflake:

APIs Parâmetro de configuração e para execução híbrida

A execução híbrida usa uma combinação da estimativa de tamanho do conjunto de dados e as operações que estão sendo aplicadas ao DataFrame para determinar a escolha do backend. Em geral, conjuntos de dados com menos de 100 mil linhas tendem a usar pandas local; aqueles com mais de 100 mil linhas tendem a usar o Snowflake, a menos que o conjunto de dados seja carregado a partir de arquivos locais.

Configuração dos custos de transferência

Para alterar o limite de alternância padrão para outro valor de limite de linha, você pode modificar a variável de ambiente antes de inicializar um DataFrame:

# Change row transfer threshold to 500k
from modin.config.envvars import SnowflakePandasTransferThreshold
SnowflakePandasTransferThreshold.put(500_000)
Copy

Definir este valor vinculará a transferência de linhas do Snowflake.

Configuração de limites de execução local

Uma vez por DataFrame é local, geralmente permanecerá local, a menos que haja necessidade de movê-lo de volta para Snowflake para uma fusão, mas há um limite superior considerado para o tamanho máximo dos dados que podem ser processados localmente. Atualmente este limite é de 10 milhões de linhas.

Verificação e configuração do back-end

Para verificar o back-end atual de sua escolha, você pode usar o df.getbackend() Comando, que retorna Pandas para execução local, ou Snowflake para a execução do pushdown.

Para definir o backend atual de escolha com set_backend ou seu alias move_to:

df_local = df.set_backend('Pandas')
Copy
df_local = df.move_to('Pandas')
Copy
df_snow = df.set_backend('Snowflake')
Copy

Você também pode definir o back-end no lugar:

df.set_backend('Pandas', inplace=True)
Copy

Para inspecionar e exibir informações sobre por que os dados foram movidos:

pd.explain_switch()
Copy

Seleção de backend de substituição manual por meio de fixação de backend

Por padrão, o Snowflake escolhe automaticamente o melhor back-end para um determinado DataFrame Operações e. Se quiser substituir a seleção automática do mecanismo, é possível desativar a ativação automática de um objeto e todos os dados resultantes produzidos por ele, usando o pan_backend() Método:

pinned_df_snow = df.move_to('Snowflake').pin_backend()
Copy

To re-enable automatic backend switching, call unpin_backend():

unpinned_df_snow = pinned_df_snow.unpin_backend()
Copy

Uso de Snowpark pandas em notebooks Snowflake

Para usar pandas on Snowflake em notebooks Snowflake, consulte pandas on Snowflake em notebooks.

Uso de Snowpark pandas em planilhas Python

Para usar Snowpark pandas, você precisa instalar o Modin selecionando modin em Packages no ambiente da planilha do Python.

Você pode selecionar o tipo de retorno da função Python em Settings > Return type. Por padrão, isso é definido como uma tabela Snowpark. Para exibir o Snowpark pandas DataFrame como resultado, você pode converter um Snowpark pandas DataFrame em um Snowpark DataFrame chamando to_snowpark(). Nenhum custo de E/S será incorrido nesta conversão.

Aqui está um exemplo de uso do Snowpark pandas com o planilhas 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
Copy

Como usar o pandas on Snowflake em procedimentos armazenados

É possível usar o pandas on Snowflake em um procedimento armazenado para criar um pipeline de dados e agendar a execução do procedimento armazenado com tarefas.

Veja como você pode criar um procedimento armazenado usando o 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}.'
$$;
Copy

Veja como você pode criar um procedimento armazenado usando a Snowflake Python API:

from snowflake.snowpark.context import get_active_session
session = get_active_session()

from snowflake.snowpark import Session

def data_transformation_pipeline(session: Session) -> str:
  import modin.pandas as pd
  import snowflake.snowpark.modin.plugin
  from datetime import datetime
  # Create a Snowpark pandas DataFrame with sample data.
  df = pd.DataFrame([[1, 'Big Bear', 8],[2, 'Big Bear', 10],[3, 'Big Bear', None],
                     [1, 'Tahoe', 3],[2, 'Tahoe', None],[3, 'Tahoe', 13],
                     [1, 'Whistler', None],['Friday', 'Whistler', 40],[3, 'Whistler', 25]],
                      columns=["DAY", "LOCATION", "SNOWFALL"])
  # Drop rows with null values.
  df = df.dropna()
  # In-place point update to fix data error.
  df.loc[df["DAY"]=="Friday","DAY"]=2
  # Save Results as a Snowflake Table
  timestamp = datetime.now().strftime("%Y_%m_%d_%H_%M")
  save_path = f"OUTPUT_{timestamp}"
  df.to_snowflake(name=save_path, if_exists="replace", index=False)
  return f'Transformed DataFrame saved to {save_path}.'


dt_pipeline_sproc = session.sproc.register(name="run_data_transformation_pipeline_sp",
                             func=data_transformation_pipeline,
                             replace=True,
                             packages=['modin', 'snowflake-snowpark-python'])
Copy

Para chamar o procedimento armazenado, é possível executar dt_pipeline_sproc() em Python ou CALL run_data_transformation_pipeline_sp() em SQL.

Como usar o pandas on Snowflake com bibliotecas de terceiros

O pandas é comumente usado com APIs de bibliotecas de terceiros para aplicativos de visualização e aprendizado de máquina. O pandas on Snowflake é interoperável com a maioria dessas bibliotecas, de modo que elas podem ser usadas sem a conversão explícita para o pandas DataFrames. No entanto, observe que a execução distribuída não costuma ser compatível com a maioria das bibliotecas de terceiros, exceto em casos de uso limitado. Portanto, isso pode levar a um desempenho mais lento em grandes conjuntos de dados.

Bibliotecas de terceiros compatíveis

As bibliotecas listadas abaixo aceitam pandas on Snowflake DataFrames como entrada, mas nem todos os seus métodos foram testados. Para obter um status detalhado da interoperabilidade em um nível de API, consulte Interoperabilidade com bibliotecas de terceiros.

  • Plotly

  • Altair

  • Seaborn

  • Matplotlib

  • Numpy

  • Scikit-learn

  • XGBoost

  • NLTK

  • Streamlit

O pandas on Snowflake atualmente tem compatibilidade limitada para certas APIs NumPy e Matplotlib, como implementação distribuída para np.where e interoperabilidade com df.plot. Converter o DataFrames pandas Snowpark via to_pandas() ao trabalhar com essas bibliotecas de terceiros evitará múltiplas chamadas de E/S.

Aqui está um exemplo com Altair para visualização e scikit-learn para aprendizado de máquina.

# Create a Snowpark session with a default connection.
session = Session.builder.create()

train = pd.read_snowflake('TITANIC')

train[['Pclass', 'Parch', 'Sex', 'Survived']].head()
Copy
    Pclass  Parch     Sex       Survived
0       3      0     male               0
1       1      0   female               1
2       3      0   female               1
3       1      0   female               1
4       3      0     male               0
import altair as alt

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

Você também pode analisar a sobrevivência com base no gênero.

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

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

Nota

Para obter um melhor desempenho, recomendamos a conversão para pandas DataFrames via to_pandas(), principalmente quando você estiver usando bibliotecas de aprendizado de máquina, como scikit-learn. No entanto, a função to_pandas() coleta todas as linhas, portanto, talvez seja melhor reduzir o tamanho do dataframe primeiro com sample(frac=0.1) ou head(10).

Bibliotecas não compatíveis

Ao usar bibliotecas de terceiros não compatíveis com um pandas on Snowflake DataFrame, recomendamos converter o pandas on Snowflake DataFrame em um pandas DataFrame chamando to_pandas() antes de passar o DataFrame para o método da biblioteca de terceiros.

Nota

Chamar to_pandas() retira seus dados do Snowflake e os coloca na memória, portanto, considere isso para grandes conjuntos de dados e casos de uso confidenciais.

Usar as funções de LLM do Snowflake Cortex com o pandas Snowpark

Você pode usar as funções de LLM do Snowflake Cortex por meio da função de aplicação do Snowpark pandas.

Você aplica a função com argumentos de palavras-chave especiais. Atualmente, as seguintes funções do Cortex são compatíveis:

O exemplo a seguir usa a função TRANSLATE em vários registros em um pandas DataFrame do Snowpark:

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

Saída:

Guten Morgen
Hallo
Auf Wiedersehen
Name: content, dtype: object

O exemplo a seguir usa a função SENTIMENT (SNOWFLAKE.CORTEX) em uma tabela Snowflake chamada reviews:

from snowflake.cortex import Sentiment

s = pd.read_snowflake("reviews")["content"]
result = s.apply(Sentiment)
result
Copy

O exemplo a seguir usa o EXTRACT_ANSWER (SNOWFLAKE.CORTEX) para responder a uma pergunta:

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

Saída:

'2012'

Nota

O pacote snowflake-ml-python deve ser instalado para usar as funções LLM do Cortex.

Limitações

pandas on Snowflake tem as seguintes limitações:

  • O pandas on Snowflake não oferece nenhuma garantia de compatibilidade com bibliotecas de terceiros OSS. A partir da versão 1.14.0a1, no entanto, o Snowpark pandas introduz compatibilidade limitada para NumPy, especificamente para o uso de np.where. Para obter mais informações, consulte Interoperabilidade do 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 Como usar o pandas on Snowflake com bibliotecas de terceiros.

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

  • Os objetos MultiIndex lentos não são suportados. Quando MultiIndex é usado, ele retorna um objeto MultiIndex pandas nativo, que requer a extração de todos os dados para o lado do cliente.

  • Not all pandas APIs have a distributed implementation in pandas on Snowflake, although some are being added. For unsupported APIs, NotImplementedError is thrown. For information about supported APIs, see the API reference documentation.

  • O pandas on Snowflake oferece compatibilidade com qualquer versão de correção do pandas 2.2.

  • Snowpark pandas cannot be referenced within Snowpark pandas apply function. You can only use native pandas inside apply.

    • Veja a seguir um exemplo:

      import modin.pandas as pd
      import pandas
      
      df.apply(lambda row: pandas.to_datetime(f"{row.date} {row.time}"), axis=1)
      
      Copy

Solução de problemas

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

Práticas recomendadas

Esta seção descreve as melhores práticas a serem seguidas ao usar o pandas on Snowflake.

  • Avoid using iterative code patterns, such as for loops, iterrows, and iteritems. 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)],
      },
)
Copy
  • Avoid calling apply, applymap, and transform, 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 of df.groupby('col1').apply('sum'), directly call df.groupby('col1').sum().

  • Chame to_pandas() antes de passar o DataFrame ou série para uma biblioteca de terceiros. O pandas on Snowflake não fornece garantia de compatibilidade com bibliotecas de terceiros.

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

  • O pandas on Snowflake fornece capacidade de clonagem rápida e zero-copy ao criar DataFrames de tabelas Snowflake usando read_snowflake.

  • Verifique novamente o tipo de resultado antes de prosseguir com outras operações e faça a conversão de tipo explícita com astype, se necessário.

    Devido à capacidade limitada de inferência de tipo, se nenhuma dica de tipo for fornecida, df.apply retornará resultados do tipo objeto (variante) mesmo que o resultado contenha todos os valores inteiros. Se outras operações exigirem que o dtype seja int, você pode fazer uma conversão de tipo explícita chamando o método astype para corrigir o tipo de coluna antes de continuar.

  • Avoid calling APIs that require evaluation and materialization unless necessary.

    APIs que não retornam Series ou Dataframe exigem avaliação e materialização adiantadas para produzir o resultado no tipo correto. O mesmo vale para métodos de plotagem. Reduza as chamadas para aquelas APIs para minimizar avaliações e materializações desnecessárias.

  • Evite chamar np.where(<cond>, <escalar>, n) em grandes conjuntos de dados. O <escalar> será transmitido para um DataFrame do tamanho de <cond>, o que pode ser lento.

  • Ao trabalhar com consultas construídas iterativamente, df.cache_result pode ser usado para materializar resultados intermediários e reduzir a avaliação repetida, melhorar a latência e reduzir a complexidade da consulta geral. Por exemplo:

    df = pd.read_snowflake('pandas_test')
    df2 = pd.pivot_table(df, index='index_col', columns='pivot_col') # expensive operation
    df3 = df.merge(df2)
    df4 = df3.where(df2 == True)
    
    Copy

    In the example above, the query to produce df2 is expensive to compute and is reused in the creation of both df3 and df4. Materializing df2 into a temporary table (making subsequent operations involving df2 a 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)
    
    Copy

Exemplos

Aqui está um exemplo de código com operações do pandas. Começamos com um DataFrame Snowpark pandas chamado pandas_test, que contém três colunas: COL_STR, COL_FLOAT e COL_INT. Para exibir o notebook associado a esses exemplos, consulte os exemplos do pandas on Snowflake no repositório 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
Copy
  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)
Copy

Em seguida, criamos um DataFrame a partir da tabela Snowflake. Nós descartamos a coluna COL_INT e então salvamos o resultado de volta no Snowflake com uma coluna chamada row_position.

# Create a DataFrame out of a Snowflake table.
df = pd.read_snowflake('pandas_test')

df.shape
Copy
(3, 3)
df.head(2)
Copy
    COL_STR  COL_FLOAT  COL_INT
0         a        2.1        1
1         b        4.2        2
df.dropna(subset=["COL_FLOAT"], inplace=True)

df
Copy
    COL_STR  COL_FLOAT  COL_INT
0         a        2.1        1
1         c        6.3        2
df.shape
Copy
(2, 3)
df.dtypes
Copy
COL_STR       object
COL_FLOAT    float64
COL_INT        int64
dtype: object
# Save the result back to Snowflake with a row_pos column.
df.reset_index(drop=True).to_snowflake('pandas_test2', if_exists='replace', index=True, index_label=['row_pos'])
Copy

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 (leitura e gravação)

# Reading and writing to Snowflake
df = pd.DataFrame({"fruit": ["apple", "orange"], "size": [3.4, 5.4], "weight": [1.4, 3.2]})
df.to_snowflake("test_table", if_exists="replace", index=False )

df_table = pd.read_snowflake("test_table")


# Generate sample CSV file
with open("data.csv", "w") as f:
    f.write('fruit,size,weight\napple,3.4,1.4\norange,5.4,3.2')
# Read from local CSV file
df_csv = pd.read_csv("data.csv")

# Generate sample JSON file
with open("data.json", "w") as f:
    f.write('{"fruit":"apple", "size":3.4, "weight":1.4},{"fruit":"orange", "size":5.4, "weight":3.2}')
# Read from local JSON file
df_json = pd.read_json('data.json')

# Upload data.json and data.csv to Snowflake stage named @TEST_STAGE
# Read CSV and JSON file from stage
df_csv = pd.read_csv('@TEST_STAGE/data.csv')
df_json = pd.read_json('@TEST_STAGE/data.json')
Copy

Para obter mais informações, consulte Entrada/Saída.

Indexação

df = pd.DataFrame({"a": [1,2,3], "b": ["x", "y", "z"]})
df.columns
Copy
Index(['a', 'b'], dtype='object')
df.index
Copy
Index([0, 1, 2], dtype='int8')
df["a"]
Copy
0    1
1    2
2    3
Name: a, dtype: int8
df["b"]
Copy
0    x
1    y
2    z
Name: b, dtype: object
df.iloc[0,1]
Copy
'x'
df.loc[df["a"] > 2]
Copy
a  b
2  3  z
df.columns = ["c", "d"]
df
Copy
     c  d
0    1  x
1    2  y
2    3  z
df = df.set_index("c")
df
Copy
   d
c
1  x
2  y
3  z
df.rename(columns={"d": "renamed"})
Copy
    renamed
c
1       x
2       y
3       z

Valores ausentes

import numpy as np
df = pd.DataFrame([[np.nan, 2, np.nan, 0],
                [3, 4, np.nan, 1],
                [np.nan, np.nan, np.nan, np.nan],
                [np.nan, 3, np.nan, 4]],
                columns=list("ABCD"))
df
Copy
     A    B   C    D
0  NaN  2.0 NaN  0.0
1  3.0  4.0 NaN  1.0
2  NaN  NaN NaN  NaN
3  NaN  3.0 NaN  4.0
df.isna()
Copy
       A      B     C      D
0   True  False  True  False
1  False  False  True  False
2   True   True  True   True
3   True  False  True  False
df.fillna(0)
Copy
     A    B    C    D
0   0.0  2.0  0.0  0.0
1   3.0  4.0  0.0  1.0
2   0.0  0.0  0.0  0.0
3   0.0  3.0  0.0  4.0
df.dropna(how="all")
Copy
     A    B   C    D
0   NaN  2.0 NaN  0.0
1   3.0  4.0 NaN  1.0
3   NaN  3.0 NaN  4.0

Conversão de tipo

df = pd.DataFrame({"int": [1,2,3], "str": ["4", "5", "6"]})
df
Copy
   int str
0    1   4
1    2   5
2    3   6
df_float = df.astype(float)
df_float
Copy
   int  str
0  1.0  4.0
1  2.0  5.0
2  3.0  6.0
df_float.dtypes
Copy
int    float64
str    float64
dtype: object
pd.to_numeric(df.str)
Copy
0    4.0
1    5.0
2    6.0
Name: str, dtype: float64
df = pd.DataFrame({'year': [2015, 2016],
                'month': [2, 3],
                'day': [4, 5]})
pd.to_datetime(df)
Copy
0   2015-02-04
1   2016-03-05
dtype: datetime64[ns]

Operações binárias

df_1 = pd.DataFrame([[1,2,3],[4,5,6]])
df_2 = pd.DataFrame([[6,7,8]])
df_1.add(df_2)
Copy
    0    1     2
0  7.0  9.0  11.0
1  NaN  NaN   NaN
s1 = pd.Series([1, 2, 3])
s2 = pd.Series([2, 2, 2])
s1 + s2
Copy
0    3
1    4
2    5
dtype: int64
df = pd.DataFrame({"A": [1,2,3], "B": [4,5,6]})
df["A+B"] = df["A"] + df["B"]
df
Copy
   A  B  A+B
0  1  4    5
1  2  5    7
2  3  6    9

Agregação

df = pd.DataFrame([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9],
                [np.nan, np.nan, np.nan]],
                columns=['A', 'B', 'C'])
df.agg(['sum', 'min'])
Copy
        A     B     C
sum  12.0  15.0  18.0
min   1.0   2.0   3.0
df.median()
Copy
A    4.0
B    5.0
C    6.0
dtype: float64

Merge

df1 = pd.DataFrame({'lkey': ['foo', 'bar', 'baz', 'foo'],
                    'value': [1, 2, 3, 5]})
df1
Copy
  lkey  value
0  foo      1
1  bar      2
2  baz      3
3  foo      5
df2 = pd.DataFrame({'rkey': ['foo', 'bar', 'baz', 'foo'],
                    'value': [5, 6, 7, 8]})
df2
Copy
  rkey  value
0  foo      5
1  bar      6
2  baz      7
3  foo      8
df1.merge(df2, left_on='lkey', right_on='rkey')
Copy
  lkey  value_x rkey  value_y
0  foo        1  foo        5
1  foo        1  foo        8
2  bar        2  bar        6
3  baz        3  baz        7
4  foo        5  foo        5
5  foo        5  foo        8
df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
                'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']})
df
Copy
  key   A
0  K0  A0
1  K1  A1
2  K2  A2
3  K3  A3
4  K4  A4
5  K5  A5
other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],
                    'B': ['B0', 'B1', 'B2']})
df.join(other, lsuffix='_caller', rsuffix='_other')
Copy
  key_caller   A key_other     B
0         K0  A0        K0    B0
1         K1  A1        K1    B1
2         K2  A2        K2    B2
3         K3  A3      None  None
4         K4  A4      None  None
5         K5  A5      None  None

Groupby

df = pd.DataFrame({'Animal': ['Falcon', 'Falcon','Parrot', 'Parrot'],
               'Max Speed': [380., 370., 24., 26.]})

df
Copy
   Animal  Max Speed
0  Falcon      380.0
1  Falcon      370.0
2  Parrot       24.0
3  Parrot       26.0
df.groupby(['Animal']).mean()
Copy
        Max Speed
Animal
Falcon      375.0
Parrot       25.0

Para obter mais informações, consulte GroupBy.

Pivô

df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
                        "bar", "bar", "bar", "bar"],
                "B": ["one", "one", "one", "two", "two",
                        "one", "one", "two", "two"],
                "C": ["small", "large", "large", "small",
                        "small", "large", "small", "small",
                        "large"],
                "D": [1, 2, 2, 3, 3, 4, 5, 6, 7],
                "E": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
df
Copy
     A    B      C  D  E
0  foo  one  small  1  2
1  foo  one  large  2  4
2  foo  one  large  2  5
3  foo  two  small  3  5
4  foo  two  small  3  6
5  bar  one  large  4  6
6  bar  one  small  5  8
7  bar  two  small  6  9
8  bar  two  large  7  9
pd.pivot_table(df, values='D', index=['A', 'B'],
                   columns=['C'], aggfunc="sum")
Copy
    C    large  small
A   B
bar one    4.0      5
    two    7.0      6
foo one    4.0      1
    two    NaN      6
df = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
                'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
                'baz': [1, 2, 3, 4, 5, 6],
                'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
df
Copy
   foo bar  baz zoo
0  one   A    1   x
1  one   B    2   y
2  one   C    3   z
3  two   A    4   q
4  two   B    5   w
5  two   C    6   t

Recursos