Utilizzare il sistema di tipi di dati di BigQuery DataFrames

Il sistema di tipi di dati di BigQuery DataFrames si basa sui tipi di dati di BigQuery. Questo design garantisce un'integrazione perfetta e un allineamento con il Google Cloud data warehouse, riflettendo i tipi integrati utilizzati per l'archiviazione dei dati in BigQuery.

Mapping dei tipi

La tabella seguente mostra gli equivalenti dei tipi di dati in BigQuery, BigQuery DataFrames e altre librerie Python, nonché i relativi livelli di supporto:

Tipo di dati BigQuery BigQuery DataFrames Integrato in Python PyArrow
Booleano BOOL pandas.BooleanDtype() bool bool_()
Numero intero INT64 pandas.Int64Dtype() int int64()
Numero in virgola mobile FLOAT64 pandas.Float64Dtype() float float64()
Stringa STRING pandas.StringDtype(storage="pyarrow") str string()
Byte BYTES pandas.ArrowDtype(pyarrow.binary()) bytes binary()
Data DATE pandas.ArrowDtype(pyarrow.date32()) datetime.date date32()
Ora TIME pandas.ArrowDtype(pyarrow.time64("us")) datetime.time time64("us")
Data/ora DATETIME pandas.ArrowDtype(pyarrow.timestamp("us")) datetime.datetime timestamp("us")
Timestamp TIMESTAMP pandas.ArrowDtype(pyarrow.timestamp("us", tz="UTC")) Datetime.datetime con fuso orario timestamp("us", tz="UTC")
Numerico NUMERIC pandas.ArrowDtype(pyarrow.decimal128(38, 9)) decimal.Decimal decimal128(38, 9)
Numero grande 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()) in pandas versione 3.0 o successive e PyArrow versione 19.0 o successive; in caso contrario, le colonne JSON vengono esposte come pandas.ArrowDtype(db_dtypes.JSONArrowType()). Questa funzionalità è in anteprima. Non supportata json_() (anteprima)
Area geografica GEOGRAPHY Geopandas.array.GeometryDtype()
Supportato solo da to_pandas().
Non supportata Non supportata
Timedelta Non supportata pandas.ArrowDtype(pyarrow.duration("us")) datetime.timedelta duration("us")

Conversioni dei tipi

Se utilizzato con i dati locali, BigQuery DataFrames converte i tipi di dati nei relativi equivalenti di BigQuery DataFrames ovunque sia definito un mapping dei tipi, come mostrato nell'esempio seguente:

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

PyArrow determina il comportamento in caso di discrepanze tra gli equivalenti dei tipi di dati. In rari casi in cui il tipo integrato di Python funziona in modo diverso dalla sua controparte PyArrow, BigQuery DataFrames in genere preferisce il comportamento PyArrow per garantire la coerenza.

Il seguente esempio di codice utilizza l'operazione datetime.date + timedelta per mostrare che, a differenza della libreria datetime di Python che restituisce ancora un'istanza di data, BigQuery DataFrames segue il comportamento PyArrow restituendo un'istanza di timestamp:

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]

Tipi speciali

Nelle sezioni che seguono vengono descritti i tipi di dati speciali utilizzati da BigQuery DataFrames.

JSON

In BigQuery DataFrames, le colonne che utilizzano il formato JSON di BigQuery (uno standard leggero) sono rappresentate da pandas.ArrowDtype. Il tipo Arrow sottostante esatto dipende dalle versioni della libreria. In genere, gli ambienti precedenti utilizzano db_dtypes.JSONArrowType() per la compatibilità, che è un tipo di estensione Arrow che funge da wrapper leggero intorno a pa.string(). Al contrario, le configurazioni più recenti (pandas 3.0 e versioni successive e PyArrow 19.0 e versioni successive) utilizzano la rappresentazione pa.json_(pa.string()) più recente.

timedelta

Il tipo timedelta non ha un equivalente diretto all'interno del sistema di tipi integrato di BigQuery. Per gestire i dati di durata, BigQuery DataFrames utilizza il tipo INT64 come formato di archiviazione sottostante nelle tabelle BigQuery. Puoi prevedere che i risultati dei calcoli siano coerenti con il comportamento che ti aspetteresti da operazioni equivalenti eseguite con la libreria pandas.

Puoi caricare direttamente i valori timedelta negli oggetti BigQuery DataFrames e Series, come mostrato nell'esempio seguente:

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]

A differenza di pandas, BigQuery DataFrames supporta solo i valori timedelta con precisione in microsecondi. Se i dati includono nanosecondi, devi arrotondarli per evitare potenziali eccezioni, come mostrato nell'esempio seguente:

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]

Puoi utilizzare la bigframes.pandas.to_timedelta funzione per trasmettere un oggetto Series di BigQuery DataFrames al tipo timedelta, come mostrato nell'esempio seguente:

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 carichi i dati contenenti valori timedelta in una tabella BigQuery, i valori vengono convertiti in microsecondi e archiviati nelle colonne INT64. Per conservare le informazioni sul tipo, BigQuery DataFrames aggiunge la stringa #microseconds alle descrizioni di queste colonne. Alcune operazioni, come le esecuzioni di query SQL e le invocazioni di UDF, non conservano le descrizioni delle colonne e le informazioni sul tipo timedelta vengono perse al termine di queste operazioni.

Strumenti per i tipi composti

Per alcuni tipi composti, BigQuery DataFrames fornisce strumenti che consentono di accedere ed elaborare i valori elementari all'interno di questi tipi.

Funzione di accesso all'elenco

L'oggetto ListAccessor può aiutarti a eseguire operazioni su ogni elemento dell'elenco utilizzando la proprietà list dell'oggetto Series, come mostrato nell'esempio seguente:

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

Funzione di accesso alla struttura

L'oggetto StructAccessor può accedere ed elaborare i campi in una serie di struct. L'oggetto di accesso all'API è series.struct, come mostrato nell'esempio seguente:

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 il campo struct a cui prevedi di accedere non è ambiguo rispetto ad altre proprietà Series, puoi saltare la chiamata a struct, come mostrato nell'esempio seguente:

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

Tuttavia, è consigliabile utilizzare struct per accedere ai campi, perché rende il codice più facile da comprendere e meno soggetto a errori.

Funzione di accesso alla stringa

Puoi accedere all'oggetto StringAccessor con la proprietà str di un oggetto Series, come mostrato nell'esempio seguente:

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

Funzione di accesso all'area geografica

BigQuery DataFrames fornisce un oggetto GeographyAccessor che condivide API simili con la struttura GeoSeries fornita dalla libreria GeoPandas. Puoi richiamare l'oggetto GeographyAccessor con la proprietà geo di un oggetto Series, come mostrato nell'esempio seguente:

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

Passaggi successivi