שימוש במערכת סוגי הנתונים של BigQuery DataFrames

מערכת סוגי הנתונים של BigQuery DataFrames מבוססת על סוגי הנתונים של BigQuery. העיצוב הזה מבטיח שילוב חלק והתאמה לGoogle Cloud מחסן הנתונים, ומשקף את הסוגים המובנים שמשמשים לאחסון נתונים ב-BigQuery.

מיפוי סוגים

בטבלה הבאה מוצגים סוגי נתונים מקבילים ב-BigQuery, ב-BigQuery DataFrames ובספריות אחרות של Python, וגם רמות התמיכה בהם:

סוג נתונים BigQuery ‫BigQuery DataFrames Python built-in PyArrow
בוליאני BOOL pandas.BooleanDtype() bool bool_()
מספר שלם INT64 pandas.Int64Dtype() int int64()
Float FLOAT64 pandas.Float64Dtype() float float64()
String 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 NUMERIC pandas.ArrowDtype(pyarrow.decimal128(38, 9)) decimal.Decimal decimal128(38, 9)
מספר גדול 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()) בגרסה 3.0 ואילך של pandas ובגרסה 19.0 ואילך של PyArrow. אחרת, עמודות 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, שמחזירה עדיין מופע של תאריך, 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, עמודות שמשתמשות בפורמט JSON של BigQuery (תקן קל משקל) מיוצגות על ידי pandas.ArrowDtype. הסוג המדויק של Arrow שמשמש כבסיס תלוי בגרסאות של הספריות שלכם. בסביבות ישנות יותר נעשה בדרך כלל שימוש ב-db_dtypes.JSONArrowType() לצורך תאימות. זהו סוג של הרחבת Arrow שפועלת כעטיפה קלה סביב pa.string(). לעומת זאת, הגדרות חדשות יותר (pandas מגרסה 3.0 ואילך ו-PyArrow מגרסה 19.0 ואילך) משתמשות בייצוג pa.json_(pa.string()) העדכני יותר.

timedelta

לסוג timedelta אין מקבילה ישירה במערכת הסוגים המובנית של BigQuery. כדי לנהל נתוני משך, BigQuery DataFrames משתמש בסוג INT64 כפורמט האחסון הבסיסי בטבלאות BigQuery. התוצאות של החישובים צפויות להיות עקביות עם ההתנהגות שצפויה מפעולות מקבילות שמתבצעות באמצעות ספריית pandas.

אפשר לטעון ישירות ערכים של timedelta לתוך אובייקטים של BigQuery DataFrames ו-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 כדי להמיר אובייקט Series של BigQuery DataFrames לסוג 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, כמו בדוגמה הבאה:

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

פונקציית גישה ל-Struct

אובייקט 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 שאתם מתכננים לגשת אליו לא משתמע לשתי פנים בהשוואה לנכסי struct אחרים, אתם יכולים לדלג על הקריאה ל-struct, כמו בדוגמה הבאה:Series

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 כדי לגשת לשדות, כי כך קל יותר להבין את הקוד ופחות סביר שיהיו בו שגיאות.

String accessor

אפשר לגשת לאובייקט StringAccessor באמצעות המאפיין str באובייקט Series, כמו בדוגמה הבאה:

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 מספק אובייקט GeographyAccessor עם ממשקי API דומים למבנה GeoSeries שמסופק על ידי ספריית GeoPandas. אפשר להפעיל את האובייקט GeographyAccessor עם המאפיין geo באובייקט Series, כמו בדוגמה הבאה:

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

המאמרים הבאים