Manipular dados com DataFrames do BigQuery

Neste documento, descrevemos as capacidades de manipulação de dados disponíveis com o BigQuery DataFrames. Você pode encontrar as funções descritas na biblioteca bigframes.bigquery.

Funções exigidas

Para conseguir as permissões necessárias a fim de concluir as tarefas neste documento, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Quando você executa a autenticação de usuário final em um ambiente interativo, como um notebook, um REPL do Python ou a linha de comando, o DataFrames do BigQuery solicita autenticação, se necessário. Caso contrário, consulte como configurar o Application Default Credentials para vários ambientes.

API pandas

Um recurso importante do BigQuery DataFrames é que a API bigframes.pandas foi projetada para ser semelhante às APIs na biblioteca pandas. Esse design permite usar padrões de sintaxe conhecidos para tarefas de manipulação de dados. As operações definidas pela API BigQuery DataFrames são executadas no lado do servidor, operando diretamente em dados armazenados no BigQuery e eliminando a necessidade de transferir conjuntos de dados para fora do BigQuery.

Para verificar quais APIs pandas são compatíveis com o BigQuery DataFrames, consulte APIs pandas compatíveis.

Inspecionar e manipular dados

É possível usar a API bigframes.pandas para realizar operações de inspeção e cálculo de dados. O exemplo de código a seguir usa a biblioteca bigframes.pandas para inspecionar a coluna body_mass_g, calcular a média body_mass e calcular a média body_mass por species:

import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"
bq_df = bpd.read_gbq(query_or_table)

# Inspect one of the columns (or series) of the DataFrame:
bq_df["body_mass_g"]

# Compute the mean of this series:
average_body_mass = bq_df["body_mass_g"].mean()
print(f"average_body_mass: {average_body_mass}")

# Find the heaviest species using the groupby operation to calculate the
# mean body_mass_g:
(
    bq_df["body_mass_g"]
    .groupby(by=bq_df["species"])
    .mean()
    .sort_values(ascending=False)
    .head(10)
)

Biblioteca do BigQuery

A biblioteca do BigQuery fornece funções SQL do BigQuery que podem não ter um equivalente no pandas. As seções a seguir apresentam alguns exemplos.

Processar valores de matriz

Você pode usar a função bigframes.bigquery.array_agg() na biblioteca bigframes.bigquery para agregar valores após uma operação groupby:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

s = bpd.Series([0, 1, 2, 3, 4, 5])

# Group values by whether they are divisble by 2 and aggregate them into arrays
bbq.array_agg(s.groupby(s % 2 == 0))
# False    [1 3 5]
# True     [0 2 4]
# dtype: list<item: int64>[pyarrow]

Também é possível usar as funções de matriz array_length() e array_to_string().

Criar um objeto struct Series

É possível usar a função bigframes.bigquery.struct() na biblioteca bigframes.bigquery para criar um novo objeto struct Series com subcampos para cada coluna em um DataFrame:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"
bq_df = bpd.read_gbq(query_or_table)

# Create a new STRUCT Series with subfields for each column in a DataFrames.
lengths = bbq.struct(
    bq_df[["culmen_length_mm", "culmen_depth_mm", "flipper_length_mm"]]
)

lengths.peek()
# 146	{'culmen_length_mm': 51.1, 'culmen_depth_mm': ...
# 278	{'culmen_length_mm': 48.2, 'culmen_depth_mm': ...
# 337	{'culmen_length_mm': 36.4, 'culmen_depth_mm': ...
# 154	{'culmen_length_mm': 46.5, 'culmen_depth_mm': ...
# 185	{'culmen_length_mm': 50.1, 'culmen_depth_mm': ...
# dtype: struct[pyarrow]

Converter carimbos de data/hora em períodos Unix

Use a função bigframes.bigquery.unix_micros() na biblioteca bigframes.bigquery para converter carimbos de data/hora em microssegundos do Unix:

import pandas as pd

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Create a series that consists of three timestamps: [1970-01-01, 1970-01-02, 1970-01-03]
s = bpd.Series(pd.date_range("1970-01-01", periods=3, freq="d", tz="UTC"))

bbq.unix_micros(s)
# 0               0
# 1     86400000000
# 2    172800000000
# dtype: Int64

Também é possível usar as funções de tempo unix_seconds() e unix_millis().

Usar a função escalar SQL

É possível usar a função bigframes.bigquery.sql_scalar() na biblioteca bigframes.bigquery para acessar uma sintaxe SQL arbitrária que representa uma expressão de coluna única:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"

# The sql_scalar function can be used to inject SQL syntax that is not supported
# or difficult to express with the bigframes.pandas APIs.
bq_df = bpd.read_gbq(query_or_table)
shortest = bbq.sql_scalar(
    "LEAST({0}, {1}, {2})",
    columns=[
        bq_df["culmen_depth_mm"],
        bq_df["culmen_length_mm"],
        bq_df["flipper_length_mm"],
    ],
)

shortest.peek()
#         0
# 149	18.9
# 33	16.3
# 296	17.2
# 287	17.0
# 307	15.0
# dtype: Float64

A seguir