Usar o sistema de tipos de dados do BigQuery DataFrames

O sistema de tipos de dados do BigQuery DataFrames permite trabalhar com estruturas de dados que se alinham aos tipos de armazenamento integrados do BigQuery. Criar suas análises com base nesses tipos de dados garante uma integração perfeita e mapeamentos de tipos confiáveis em todo o data warehouse.

Mapeamentos de tipo

A tabela a seguir mostra os equivalentes de tipo de dados no BigQuery, no BigQuery DataFrames e em outras bibliotecas Python, bem como os níveis de suporte:

Tipo de dado BigQuery BigQuery DataFrames Python integrado PyArrow
Booleano BOOL pandas.BooleanDtype() bool bool_()
Número inteiro INT64 pandas.Int64Dtype() int int64()
Ponto flutuante FLOAT64 pandas.Float64Dtype() float float64()
String STRING pandas.StringDtype(storage="pyarrow") str string()
Bytes BYTES pandas.ArrowDtype(pyarrow.binary()) bytes binary()
Data DATE pandas.ArrowDtype(pyarrow.date32()) datetime.date date32()
Hora TIME pandas.ArrowDtype(pyarrow.time64("us")) datetime.time time64("us")
Data/hora DATETIME pandas.ArrowDtype(pyarrow.timestamp("us")) datetime.datetime timestamp("us")
Carimbo de data/hora TIMESTAMP pandas.ArrowDtype(pyarrow.timestamp("us", tz="UTC")) Datetime.datetime com fuso horário timestamp("us", tz="UTC")
Numérico NUMERIC pandas.ArrowDtype(pyarrow.decimal128(38, 9)) decimal.Decimal decimal128(38, 9)
Big numeric BIGNUMERIC pandas.ArrowDtype(pyarrow.decimal256(76, 38)) decimal.Decimal decimal256(76, 38)
List<T> ARRAY<T> pandas.ArrowDtype(pyarrow.list_(T)) list[T] list_(T)
Struct STRUCT pandas.ArrowDtype(pyarrow.struct()) dict struct()
JSON JSON pandas.ArrowDtype(pyarrow.json_(pa.string()) no pandas versão 3.0 ou mais recente e no PyArrow versão 19.0 ou mais recente. Caso contrário, as colunas JSON serão expostas como pandas.ArrowDtype(db_dtypes.JSONArrowType()). Esse recurso está na visualização. Sem suporte json_() (Pré-lançamento)
Geografia GEOGRAPHY Geopandas.array.GeometryDtype()
Compatível apenas com to_pandas().
Sem suporte Sem suporte
Timedelta Sem suporte pandas.ArrowDtype(pyarrow.duration("us")) datetime.timedelta duration("us")

Conversões de tipos

Quando usado com dados locais, o BigQuery DataFrames converte os tipos de dados nos equivalentes do BigQuery DataFrames sempre que um mapeamento de tipo é definido, conforme mostrado no exemplo a seguir:

import pandas as pd

import bigframes.pandas as bpd

s = pd.Series([pd.Timestamp("20250101")])
assert s.dtype == "datetime64[ns]"
assert bpd.read_pandas(s).dtype == "timestamp[us][pyarrow]"

O PyArrow dita o comportamento quando há discrepâncias entre os equivalentes de tipo de dados. Em casos raros em que o tipo integrado do Python funciona de maneira diferente da contraparte do PyArrow, o BigQuery DataFrames geralmente favorece o comportamento do PyArrow para garantir a consistência.

O exemplo de código a seguir usa a operação datetime.date + timedelta para mostrar que, ao contrário da biblioteca datetime do Python, que ainda retorna uma instância de data, o BigQuery DataFrames segue o comportamento do PyArrow retornando uma instância de carimbo de data/hora:

import datetime

import pandas as pd

import bigframes.pandas as bpd

s = pd.Series([datetime.date(2025, 1, 1)])
s + pd.Timedelta(hours=12)
# 0	2025-01-01
# dtype: object

bpd.read_pandas(s) + pd.Timedelta(hours=12)
# 0    2025-01-01 12:00:00
# dtype: timestamp[us][pyarrow]

Tipos especiais

As seções a seguir descrevem os tipos de dados especiais usados pelo BigQuery DataFrames.

JSON

No BigQuery DataFrames, as colunas que usam o formato JSON do BigQuery (um padrão leve) são representadas por pandas.ArrowDtype. O tipo exato de Arrow depende das versões da biblioteca. Os ambientes mais antigos normalmente usam db_dtypes.JSONArrowType() para compatibilidade, que é um tipo de extensão Arrow que atua como um wrapper leve em torno de pa.string(). Por outro lado, as configurações mais recentes (pandas 3.0 e versões mais recentes e PyArrow 19.0 e versões mais recentes) usam a representação pa.json_(pa.string()) mais recente.

timedelta

O tipo timedelta não tem um equivalente direto no sistema de tipos integrado do BigQuery. Para gerenciar dados de duração, o BigQuery DataFrames usa o tipo INT64 como o formato de armazenamento subjacente nas tabelas do BigQuery. Os resultados dos cálculos serão consistentes com o comportamento esperado de operações equivalentes realizadas com a biblioteca pandas.

É possível carregar diretamente valores timedelta em BigQuery DataFrames e objetos Series, conforme mostrado no exemplo a seguir:

import pandas as pd

import bigframes.pandas as bpd

s = pd.Series([pd.Timedelta("1s"), pd.Timedelta("2m")])
bpd.read_pandas(s)
# 0    0 days 00:00:01
# 1    0 days 00:02:00
# dtype: duration[us][pyarrow]

Ao contrário do pandas, o BigQuery DataFrames só aceita valores timedelta com precisão de microssegundos. Se os dados incluírem nanossegundos, arredonde-os para evitar possíveis exceções, como mostrado no exemplo a seguir:

import pandas as pd

s = pd.Series([pd.Timedelta("999ns")])
bpd.read_pandas(s.dt.round("us"))
# 0    0 days 00:00:00.000001
# dtype: duration[us][pyarrow]

Use a função bigframes.pandas.to_timedelta para converter um objeto Series do BigQuery DataFrames no tipo timedelta, conforme mostrado no exemplo a seguir:

import bigframes.pandas as bpd

bpd.to_timedelta([1, 2, 3], unit="s")
# 0    0 days 00:00:01
# 1    0 days 00:00:02
# 2    0 days 00:00:03
# dtype: duration[us][pyarrow]

Quando você carrega dados que contêm valores timedelta em uma tabela do BigQuery, os valores são convertidos em microssegundos e armazenados em colunas INT64. Para preservar as informações de tipo, o BigQuery DataFrames anexa a string #microseconds às descrições dessas colunas. Algumas operações, como execuções de consulta SQL e invocações de UDF, não preservam as descrições de colunas, e as informações do tipo timedelta são perdidas após a conclusão dessas operações.

Ferramentas para tipos compostos

Para determinados tipos compostos, o BigQuery DataFrames oferece ferramentas que permitem acessar e processar os valores elementares dentro desses tipos.

Acessador de lista

O objeto ListAccessor pode ajudar você a realizar operações em cada elemento da lista usando a propriedade de lista do objeto Series, conforme mostrado no exemplo a seguir:

import bigframes.pandas as bpd

s = bpd.Series([[1, 2, 3], [4, 5], [6]])  # dtype: list<item: int64>[pyarrow]

# Access the first elements of each list
s.list[0]
# 0    1
# 1    4
# 2    6
# dtype: Int64

# Get the lengths of each list
s.list.len()
# 0    3
# 1    2
# 2    1
# dtype: Int64

Acessador de struct

O objeto StructAccessor pode acessar e processar campos em uma série de estruturas. O objeto de acesso da API é series.struct, conforme mostrado no exemplo a seguir:

import bigframes.pandas as bpd

structs = [
    {"id": 101, "category": "A"},
    {"id": 102, "category": "B"},
    {"id": 103, "category": "C"},
]
s = bpd.Series(structs)
# Get the 'id' field of each struct
s.struct.field("id")
# 0    101
# 1    102
# 2    103
# Name: id, dtype: Int64

Se o campo struct que você planeja acessar não for ambíguo em relação a outras propriedades Series, pule a chamada de struct, como mostrado no exemplo a seguir:

import bigframes.pandas as bpd

structs = [
    {"id": 101, "category": "A"},
    {"id": 102, "category": "B"},
    {"id": 103, "category": "C"},
]
s = bpd.Series(structs)

# not explicitly using the "struct" property
s.id
# 0    101
# 1    102
# 2    103
# Name: id, dtype: Int64

No entanto, é uma prática recomendada usar struct para acessar campos, porque isso facilita a compreensão do código e reduz a probabilidade de erros.

Acessador de string

É possível acessar o objeto StringAccessor com a propriedade str em um objeto Series, conforme mostrado no exemplo a seguir:

import bigframes.pandas as bpd

s = bpd.Series(["abc", "de", "1"])  # dtype: string[pyarrow]

# Get the first character of each string
s.str[0]
# 0    a
# 1    d
# 2    1
# dtype: string

# Check whether there are only alphabetic characters in each string
s.str.isalpha()
# 0     True
# 1     True
# 2     False
# dtype: boolean

# Cast the alphabetic characters to their upper cases for each string
s.str.upper()
# 0    ABC
# 1     DE
# 2      1
# dtype: string

Acessador de geografia

O BigQuery DataFrames fornece um objeto GeographyAccessor que compartilha APIs semelhantes com a estrutura GeoSeries fornecida pela biblioteca GeoPandas. É possível invocar o objeto GeographyAccessor com a propriedade geo em um objeto Series, conforme mostrado no exemplo a seguir:

from shapely.geometry import Point

import bigframes.pandas as bpd

s = bpd.Series([Point(1, 0), Point(2, 1)])  # dtype: geometry

s.geo.y
# 0    0.0
# 1    1.0
# dtype: Float64

A seguir