使用 BigQuery DataFrames 操控資料

BigQuery DataFrames 可讓您使用熟悉的 pandas 語法模式操控資料,不必將資料集移出資料倉儲。由於這些作業是在伺服器端執行,因此您可以直接檢查、操控及套用複雜的計算,處理儲存在 BigQuery 資料儲存庫中的資料。

如要進一步瞭解支援的函式,請參閱 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() 陣列函式。

建立 struct Series 物件

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

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 紀元

您可以使用 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

後續步驟