⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
Jupyter Notebooks

DuckDB 的 Python 客户端如果需要,可以直接在 Jupyter Notebook 中使用,无需额外配置。然而,可以使用额外的库来简化 SQL 查询开发。本指南将介绍如何利用这些额外的库。有关如何将 DuckDB 和 Python 结合使用的信息,请参阅 Python 部分的其他指南。

在此示例中,我们使用 JupySQL 包。此示例工作流也可以通过 Google Colab notebook 获取。

库安装

四个额外的库可以改善 Jupyter Notebooks 中的 DuckDB 使用体验。

  1. jupysql: 将 Jupyter 代码单元格转换为 SQL 单元格
  2. Pandas: 清晰的表格可视化以及与其他分析的兼容性
  3. matplotlib: 使用 Python 绘图
  4. duckdb-engine (DuckDB SQLAlchemy 驱动): 由 SQLAlchemy 用于连接 DuckDB(可选)

如果 Jupyter Notebook 尚未安装,请从命令行运行这些 pip install 命令。否则,请参阅上面的 Google Colab 链接以获取 Notebook 内的示例。

pip install duckdb

安装 Jupyter Notebook

pip install notebook

或 JupyterLab

pip install jupyterlab

安装支持库

pip install jupysql pandas matplotlib duckdb-engine

库导入和配置

打开 Jupyter Notebook 并导入相关库。

在 jupysql 上设置配置,以便直接将数据输出到 Pandas 并简化打印到 Notebook 的输出。

%config SqlMagic.autopandas = True
%config SqlMagic.feedback = False
%config SqlMagic.displaycon = False

原生连接到 DuckDB

要连接到 DuckDB,请运行

import duckdb
import pandas as pd

%load_ext sql
conn = duckdb.connect()
%sql conn --alias duckdb

警告:原生 DuckDB 连接中不识别 变量

通过 SQLAlchemy 连接到 DuckDB

或者,您可以使用 duckdb_engine 通过 SQLAlchemy 连接到 DuckDB。请参阅性能和功能差异

import duckdb
import pandas as pd
# No need to import duckdb_engine
#  jupysql will auto-detect the driver needed based on the connection string!

# Import jupysql Jupyter extension to create SQL cells
%load_ext sql

可以连接到新的内存中的 DuckDB默认连接或文件支持的数据库。

%sql duckdb:///:memory:
%sql duckdb:///:default:
%sql duckdb:///path/to/file.db

如果将 duckdb:///:default: 作为 SQLAlchemy 连接字符串提供,则 %sql 命令和 duckdb.sql 共享相同的默认连接

查询 DuckDB

单行 SQL 查询可以在行首使用 %sql 运行。查询结果将显示为 Pandas DataFrame。

%sql SELECT 'Off and flying!' AS a_duckdb_column;

通过在单元格开头放置 %%sql,整个 Jupyter 单元格可以用作 SQL 单元格。查询结果将显示为 Pandas DataFrame。

%%sql
SELECT
    schema_name,
    function_name
FROM duckdb_functions()
ORDER BY ALL DESC
LIMIT 5;

要将查询结果存储在 Python 变量中,请使用 << 作为赋值运算符。这可以与 %sql%%sql Jupyter magic 命令一起使用。

%sql res << SELECT 'Off and flying!' AS a_duckdb_column;

如果设置了 %config SqlMagic.autopandas = True 选项,则该变量是一个 Pandas 数据框;否则,它是一个 ResultSet,可以通过 DataFrame() 函数转换为 Pandas。

查询 Pandas DataFrames

DuckDB 能够找到并查询 Jupyter Notebook 中以变量形式存储的任何数据框。

input_df = pd.DataFrame.from_dict({"i": [1, 2, 3],
                                   "j": ["one", "two", "three"]})

被查询的数据框可以在 FROM 子句中像其他任何表一样指定。

%sql output_df << SELECT sum(i) AS total_i FROM input_df;

警告:当使用 SQLAlchemy 连接且 DuckDB 版本 >= 1.1.0 时,请确保运行 %sql SET python_scan_all_frames=true,以使 Pandas 数据框可查询。

可视化 DuckDB 数据

在 Python 中绘制数据集最常见的方法是使用 Pandas 加载它们,然后使用 matplotlib 或 seaborn 进行绘图。这种方法需要将所有数据加载到内存中,效率极低。JupySQL 中的绘图模块在 SQL 引擎中运行计算。这将内存管理委托给引擎,并确保中间计算不会持续占用内存,从而高效地绘制大量数据集。

箱线图和直方图

要创建箱线图,请调用 %sqlplot boxplot,并传递表名和要绘制的列名。在此示例中,表名是本地存储的 Parquet 文件的路径。

from urllib.request import urlretrieve

_ = urlretrieve(
    "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet",
    "yellow_tripdata_2021-01.parquet",
)

%sqlplot boxplot --table yellow_tripdata_2021-01.parquet --column trip_distance

Boxplot of the trip_distance column

安装并加载 DuckDB httpfs 扩展

DuckDB 的 httpfs 扩展允许通过 http 远程查询 Parquet 和 CSV 文件。这些示例查询包含纽约市历史出租车数据的 Parquet 文件。使用 Parquet 格式允许 DuckDB 只将所需的行和列拉入内存,而不是下载整个文件。DuckDB 也可以用于处理本地 Parquet 文件,如果查询整个 Parquet 文件或运行需要文件大子集的多个查询,这可能是可取的。

%%sql
INSTALL httpfs;
LOAD httpfs;

现在,创建一个按第 90 百分位数过滤的查询。请注意 --save--no-execute 函数的使用。这会告诉 JupySQL 存储查询,但跳过执行。它将在下一个绘图调用中被引用。

%%sql --save short_trips --no-execute
SELECT *
FROM 'https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet'
WHERE trip_distance < 6.3

要创建直方图,请调用 %sqlplot histogram 并传递表名、要绘制的列名和 bin 数量。这使用了 --with short-trips,因此 JupySQL 使用之前定义的查询,从而只绘制数据的子集。

%sqlplot histogram --table short_trips --column trip_distance --bins 10 --with short_trips

Histogram of the trip_distance column

总结

现在,您能够以简单且高性能的方式在 SQL 和 Pandas 之间切换!您可以直接通过引擎绘制大量数据集(避免下载整个文件和将其全部加载到 Pandas 内存中)。数据框可以在 SQL 中作为表读取,SQL 结果可以输出到 DataFrames。祝您分析愉快!

jupysql 的替代方案是 magic_duckdb