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

BigQuery DataFrames のデータ型システムは、BigQuery のデータ型に基づいて構築されています。この設計により、Google Cloud データ ウェアハウスとのシームレスな統合と整合性が確保され、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

次のステップ