使用 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 库提供了一些可能没有 pandas 等效函数的 BigQuery SQL 函数。以下部分提供了一些示例。

处理数组值

您可以使用 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() 函数创建新的结构体 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

后续步骤