使用 BigQuery DataFrames 操作資料

本文說明 BigQuery DataFrames 提供的資料操控功能。您可以在 bigframes.bigquery 程式庫中找到所述函式。

必要的角色

如要取得完成本文件工作所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

在筆記本、Python REPL 或指令列等互動式環境中執行使用者驗證時,BigQuery DataFrames 會視需要提示進行驗證。否則,請參閱如何為各種環境設定應用程式預設憑證

pandas API

BigQuery DataFrames 的顯著特色是,bigframes.pandas API 的設計與 pandas 程式庫中的 API 相似。這種設計可讓您使用熟悉的語法模式執行資料操縱工作。透過 BigQuery DataFrames API 定義的作業會在伺服器端執行,直接對 BigQuery 中儲存的資料進行操作,因此不需要將資料集移出 BigQuery。

如要查看 BigQuery DataFrames 支援哪些 pandas API,請參閱「支援的 pandas API」。

檢查及操控資料

您可以使用 bigframes.pandas API 執行資料檢查和計算作業。以下程式碼範例使用 bigframes.pandas 程式庫檢查 body_mass_g 欄、計算平均值 body_mass,以及依 species 計算平均值 body_mass

import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"
bq_df = bpd.read_gbq(query_or_table)

# Inspect one of the columns (or series) of the DataFrame:
bq_df["body_mass_g"]

# Compute the mean of this series:
average_body_mass = bq_df["body_mass_g"].mean()
print(f"average_body_mass: {average_body_mass}")

# Find the heaviest species using the groupby operation to calculate the
# mean body_mass_g:
(
    bq_df["body_mass_g"]
    .groupby(by=bq_df["species"])
    .mean()
    .sort_values(ascending=False)
    .head(10)
)

BigQuery 程式庫

BigQuery 程式庫提供 BigQuery SQL 函式,這些函式可能沒有對應的 pandas 函式。以下各節提供一些範例。

處理陣列值

您可以在 bigframes.bigquery 程式庫中使用 bigframes.bigquery.array_agg() 函式,在 groupby 作業後匯總值:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

s = bpd.Series([0, 1, 2, 3, 4, 5])

# Group values by whether they are divisble by 2 and aggregate them into arrays
bbq.array_agg(s.groupby(s % 2 == 0))
# False    [1 3 5]
# True     [0 2 4]
# dtype: list<item: int64>[pyarrow]

您也可以使用 array_length()array_to_string() 陣列函式。

建立結構體 Series 物件

您可以在 bigframes.bigquery 程式庫中使用 bigframes.bigquery.struct() 函式,為 DataFrame 中的每個資料欄建立具有子欄位的新 struct Series 物件:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"
bq_df = bpd.read_gbq(query_or_table)

# Create a new STRUCT Series with subfields for each column in a DataFrames.
lengths = bbq.struct(
    bq_df[["culmen_length_mm", "culmen_depth_mm", "flipper_length_mm"]]
)

lengths.peek()
# 146	{'culmen_length_mm': 51.1, 'culmen_depth_mm': ...
# 278	{'culmen_length_mm': 48.2, 'culmen_depth_mm': ...
# 337	{'culmen_length_mm': 36.4, 'culmen_depth_mm': ...
# 154	{'culmen_length_mm': 46.5, 'culmen_depth_mm': ...
# 185	{'culmen_length_mm': 50.1, 'culmen_depth_mm': ...
# dtype: struct[pyarrow]

將時間戳記轉換為 Unix Epoch

您可以使用 bigframes.bigquery 程式庫中的 bigframes.bigquery.unix_micros() 函式,將時間戳記轉換為 Unix 毫秒:

import pandas as pd

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Create a series that consists of three timestamps: [1970-01-01, 1970-01-02, 1970-01-03]
s = bpd.Series(pd.date_range("1970-01-01", periods=3, freq="d", tz="UTC"))

bbq.unix_micros(s)
# 0               0
# 1     86400000000
# 2    172800000000
# dtype: Int64

您也可以使用 unix_seconds()unix_millis() 時間函式。

使用 SQL 純量函式

您可以在 bigframes.bigquery 程式庫中使用 bigframes.bigquery.sql_scalar() 函式,存取代表單欄運算式的任意 SQL 語法:

import bigframes.bigquery as bbq
import bigframes.pandas as bpd

# Load data from BigQuery
query_or_table = "bigquery-public-data.ml_datasets.penguins"

# The sql_scalar function can be used to inject SQL syntax that is not supported
# or difficult to express with the bigframes.pandas APIs.
bq_df = bpd.read_gbq(query_or_table)
shortest = bbq.sql_scalar(
    "LEAST({0}, {1}, {2})",
    columns=[
        bq_df["culmen_depth_mm"],
        bq_df["culmen_length_mm"],
        bq_df["flipper_length_mm"],
    ],
)

shortest.peek()
#         0
# 149	18.9
# 33	16.3
# 296	17.2
# 287	17.0
# 307	15.0
# dtype: Float64

後續步驟