Usar o sistema de tipos de dados do BigQuery DataFrames

O sistema de tipos de dados do BigQuery DataFrames é criado com base nos tipos de dados do BigQuery. Esse design garante integração e alinhamento perfeitos com o Trusted Cloud by S3NS data warehouse, refletindo os tipos integrados usados para armazenamento de dados no BigQuery.

Mapeamentos de tipo

A tabela a seguir mostra equivalentes de tipos de dados no BigQuery, no DataFrames do BigQuery e em outras bibliotecas Python, além dos 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)
Número grande BIGNUMERIC pandas.ArrowDtype(pyarrow.decimal256(76, 38)) decimal.Decimal decimal256(76, 38)
List 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()) na versão 3.0 ou mais recente do pandas e na versão 19.0 ou mais recente do PyArrow. 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 DataFrames do BigQuery converte tipos de dados nos equivalentes do DataFrames do BigQuery 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 determina 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 DataFrames do BigQuery 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 pelos DataFrames do BigQuery.

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 do Arrow depende das versões da biblioteca. Ambientes mais antigos geralmente usam db_dtypes.JSONArrowType() para compatibilidade, que é um tipo de extensão do Arrow que funciona como um wrapper leve em torno de pa.string(). Em contraste, 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 nativos do BigQuery. Para gerenciar dados de duração, o DataFrames do BigQuery usa o tipo INT64 como formato de armazenamento nas tabelas do BigQuery. Os resultados dos seus cálculos serão consistentes com o comportamento esperado de operações equivalentes realizadas com a biblioteca pandas.

É possível carregar valores timedelta diretamente em DataFrames do BigQuery 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 DataFrames do BigQuery 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]

Você pode usar a função bigframes.pandas.to_timedelta para converter um objeto Series do DataFrames do BigQuery 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 DataFrames do BigQuery 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 de tipo timedelta são perdidas após a conclusão dessas operações.

Ferramentas para tipos compostos

Para alguns tipos compostos, o BigQuery DataFrames oferece ferramentas que permitem acessar e processar os valores elementares nesses tipos.

Assistente de acesso à lista

O objeto ListAccessor pode ajudar você a realizar operações em cada elemento da lista usando a propriedade "list" do objeto Series, como 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 à 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, 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)

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

No entanto, a 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 oferece um objeto GeographyAccessor que compartilha APIs semelhantes com a estrutura GeoSeries fornecida pela biblioteca GeoPandas. Você pode 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