BigQuery DataFrames のデータ型システムを使用する

BigQuery DataFrames のデータ型システムは、BigQuery のデータ型に基づいて構築されています。この設計により、Trusted Cloud by S3NS データ ウェアハウスとのシームレスな統合と整合性が確保され、BigQuery でデータ ストレージに使用される組み込み型が反映されます。

型マッピング

次の表に、BigQuery、BigQuery DataFrames、その他の Python ライブラリのデータ型と、サポートレベルを示します。

データ型 BigQuery BigQuery DataFrames Python 組み込み PyArrow
ブール値 BOOL pandas.BooleanDtype() bool bool_()
整数 INT64 pandas.Int64Dtype() int int64()
浮動小数点数 FLOAT64 pandas.Float64Dtype() float float64()
文字列 STRING pandas.StringDtype(storage="pyarrow") str string()
バイト BYTES pandas.ArrowDtype(pyarrow.binary()) bytes binary()
日付 DATE pandas.ArrowDtype(pyarrow.date32()) datetime.date date32()
時間 TIME pandas.ArrowDtype(pyarrow.time64("us")) datetime.time time64("us")
日時 DATETIME pandas.ArrowDtype(pyarrow.timestamp("us")) datetime.datetime timestamp("us")
タイムスタンプ TIMESTAMP pandas.ArrowDtype(pyarrow.timestamp("us", tz="UTC")) タイムゾーン付きの Datetime.datetime timestamp("us", tz="UTC")
数値 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 ARRAY<T> pandas.ArrowDtype(pyarrow.list_(T)) list[T] list_(T)
構造体 STRUCT pandas.ArrowDtype(pyarrow.struct()) dict struct()
JSON JSON pandas バージョン 3.0 以降と PyArrow バージョン 19.0 以降の pandas.ArrowDtype(pyarrow.json_(pa.string())。それ以外の場合、JSON 列は pandas.ArrowDtype(db_dtypes.JSONArrowType()) として公開されます。この機能はプレビュー版です。 非対応 json_()プレビュー
地域 GEOGRAPHY Geopandas.array.GeometryDtype()
to_pandas() でのみサポートされています。
非対応 非対応
Timedelta 非対応 pandas.ArrowDtype(pyarrow.duration("us")) datetime.timedelta duration("us")

型変換

ローカルデータで使用する場合、BigQuery DataFrames は、次の例に示すように、型マッピングが定義されている場所でデータ型を対応する BigQuery DataFrames の同等型に変換します。

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 は動作を決定します。Python の組み込み型が PyArrow の対応する型と異なる動作をするまれなケースでは、通常、BigQuery DataFrames は一貫性を確保するために PyArrow の動作を優先します。

次のコードサンプルでは、datetime.date + timedelta オペレーションを使用して、日付インスタンスを返す Python datetime ライブラリとは異なり、BigQuery DataFrames がタイムスタンプ インスタンスを返すことで PyArrow の動作に従っていることを示しています。

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]

特殊なタイプ

以降のセクションでは、BigQuery DataFrames で使用される特殊なデータ型について説明します。

JSON

BigQuery DataFrames 内では、BigQuery の JSON 形式(軽量標準)を使用する列は pandas.ArrowDtype で表されます。基盤となる Arrow の型は、ライブラリのバージョンによって異なります。古い環境では、通常、互換性のために db_dtypes.JSONArrowType() が使用されます。これは、pa.string() の軽量ラッパーとして機能する Arrow 拡張型です。一方、新しい設定(pandas 3.0 以降と PyArrow 19.0 以降)では、より新しい pa.json_(pa.string()) 表現が使用されます。

timedelta

timedelta 型には、BigQuery ネイティブ型システム内に直接対応する型がありません。期間データを管理するために、BigQuery DataFrames は BigQuery テーブルの基盤となるストレージ形式として INT64 型を使用します。計算結果は、pandas ライブラリで同等のオペレーションを実行した場合の動作と一致します。

次の例に示すように、timedelta 値を BigQuery DataFrame と Series オブジェクトに直接読み込むことができます。

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]

pandas とは異なり、BigQuery DataFrames はマイクロ秒単位の精度の timedelta 値のみをサポートします。データにナノ秒が含まれている場合は、次の例に示すように、例外が発生しないように丸める必要があります。

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]

次の例に示すように、bigframes.pandas.to_timedelta 関数を使用して、BigQuery DataFrames の Series オブジェクトを timedelta 型にキャストできます。

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]

timedelta 値を含むデータを BigQuery テーブルに読み込むと、値はマイクロ秒に変換され、INT64 列に保存されます。型情報を保持するため、BigQuery DataFrames はこれらの列の説明に #microseconds 文字列を追加します。SQL クエリの実行や UDF の呼び出しなどの一部のオペレーションでは、列の説明が保持されません。これらのオペレーションが完了すると、timedelta 型の情報が失われます。

複合タイプのツール

特定の複合型の場合、BigQuery DataFrames には、これらの型内の要素値にアクセスして処理できるツールが用意されています。

リスト アクセサ

ListAccessor オブジェクトは、次の例に示すように、Series オブジェクトの list プロパティを使用して、各リスト要素に対してオペレーションを実行するのに役立ちます。

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

構造体アクセサ

StructAccessor オブジェクトは、一連の構造体内のフィールドにアクセスして処理できます。API アクセサー オブジェクトは series.struct です。次の例をご覧ください。

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

アクセスする struct フィールドが他の Series プロパティと区別できる場合は、次の例に示すように struct の呼び出しをスキップできます。

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

ただし、struct を使用してフィールドにアクセスすることをおすすめします。これにより、コードが理解しやすくなり、エラーが発生しにくくなります。

文字列アクセサー

次の例に示すように、Series オブジェクトの str プロパティを使用して StringAccessor オブジェクトにアクセスできます。

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

地理情報アクセサ

BigQuery DataFrames には、GeoPandas ライブラリで提供される GeoSeries 構造と同様の API を共有する GeographyAccessor オブジェクトが用意されています。次の例に示すように、Series オブジェクトの geo プロパティを使用して GeographyAccessor オブジェクトを呼び出すことができます。

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

次のステップ