一、关于 Ibis
Ibis 是一个便携式 Python dataframe 库:
- 快速本地数据框(默认通过 DuckDB)
- 懒惰的数据框表达式
- 交互式模式,用于迭代数据探索
- 组合 Python 数据框和 SQL 代码
- 使用相同的 [近 20 个后端] 数据框 API
- 通过更改单行代码在本地迭代并在远程部署 [可移植性]
二、入门
您可以使用 pip install
安装 Ibis 以及后端和示例数据:
pip install 'ibis-framework[duckdb,examples]'
更多可见 安装指南:https://ibis-project.org/install
然后使用 Ibis:
>>> import ibis
>>> ibis.options.interactive = True
>>> t = ibis.examples.penguins.fetch()
>>> t
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┓
┃ species ┃ island ┃ bill_length_mm ┃ bill_depth_mm ┃ flipper_length_mm ┃ body_mass_g ┃ sex ┃ year ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━┩
│ string │ string │ float64 │ float64 │ int64 │ int64 │ string │ int64 │
├─────────┼───────────┼────────────────┼───────────────┼───────────────────┼─────────────┼────────┼───────┤
│ Adelie │ Torgersen │ 39.1 │ 18.7 │ 181 │ 3750 │ male │ 2007 │
│ Adelie │ Torgersen │ 39.5 │ 17.4 │ 186 │ 3800 │ female │ 2007 │
│ Adelie │ Torgersen │ 40.3 │ 18.0 │ 195 │ 3250 │ female │ 2007 │
│ Adelie │ Torgersen │ NULL │ NULL │ NULL │ NULL │ NULL │ 2007 │
│ Adelie │ Torgersen │ 36.7 │ 19.3 │ 193 │ 3450 │ female │ 2007 │
│ Adelie │ Torgersen │ 39.3 │ 20.6 │ 190 │ 3650 │ male │ 2007 │
│ Adelie │ Torgersen │ 38.9 │ 17.8 │ 181 │ 3625 │ female │ 2007 │
│ Adelie │ Torgersen │ 39.2 │ 19.6 │ 195 │ 4675 │ male │ 2007 │
│ Adelie │ Torgersen │ 34.1 │ 18.1 │ 193 │ 3475 │ NULL │ 2007 │
│ Adelie │ Torgersen │ 42.0 │ 20.2 │ 190 │ 4250 │ NULL │ 2007 │
│ … │ … │ … │ … │ … │ … │ … │ … │
└─────────┴───────────┴────────────────┴───────────────┴───────────────────┴─────────────┴────────┴───────┘
>>> g = t.group_by("species", "island").agg(count=t.count()).order_by("count")
>>> g
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
┃ species ┃ island ┃ count ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
│ string │ string │ int64 │
├───────────┼───────────┼───────┤
│ Adelie │ Biscoe │ 44 │
│ Adelie │ Torgersen │ 52 │
│ Adelie │ Dream │ 56 │
│ Chinstrap │ Dream │ 68 │
│ Gentoo │ Biscoe │ 124 │
└───────────┴───────────┴───────┘
💡 查看完整的 Ibis 介绍,请参阅入门教程。
三、Python + SQL: 一起更佳
对于大多数后端,Ibis 通过将其 dataframe 表达式编译成 SQL 来工作:
>>> ibis.to_sql(g)
SELECT
"t1"."species", "t1"."island", "t1"."count"
FROM (
SELECT
"t0"."species", "t0"."island", COUNT(*) AS "count"
FROM "penguins" AS "t0"
GROUP BY
1, 2
) AS "t1"
ORDER BY
"t1"."count" ASC
您可以混合 SQL 和 Python 代码:
>>> a = t.sql("SELECT species, island, count(*) AS count FROM penguins GROUP BY 1, 2")
>>> a
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
┃ species ┃ island ┃ count ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
│ string │ string │ int64 │
├───────────┼───────────┼───────┤
│ Adelie │ Torgersen │ 52 │
│ Adelie │ Biscoe │ 44 │
│ Adelie │ Dream │ 56 │
│ Gentoo │ Biscoe │ 124 │
│ Chinstrap │ Dream │ 68 │
└───────────┴───────────┴───────┘
>>> b = a.order_by("count")
>>> b
┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓
┃ species ┃ island ┃ count ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━┩
│ string │ string │ int64 │
├───────────┼───────────┼───────┤
│ Adelie │ Biscoe │ 44 │
│ Adelie │ Torgersen │ 52 │
│ Adelie │ Dream │ 56 │
│ Chinstrap │ Dream │ 68 │
│ Gentoo │ Biscoe │ 124 │
└───────────┴───────────┴───────┘
这使您能够结合Python的灵活性与现代SQL的规模和性能。
四、后端
Ibis 支持近 20 个后端:
- Apache DataFusion
- Apache Druid
- Apache Flink
- Apache Impala
- Apache PySpark
- BigQuery
- ClickHouse
- DuckDB
- Exasol
- MySQL
- Oracle
- Polars
- PostgreSQL
- RisingWave
- SQL Server
- SQLite
- Snowflake
- Theseus
- Trino
五、它是如何工作的
大多数 Python 数据帧与其执行引擎紧密耦合。许多数据库仅支持 SQL,没有 Python API。Ibis 通过提供 Python 中数据操作的共同 API 并将该 API 编译成后端的原生语言来解决此问题。这意味着您可以学习单个 API 并在所有支持的后端(执行引擎)中使用它。
Ibis广泛支持两种后端类型:
1、SQL生成后端
2、生成 DataFrame 的后端
六、可移植性
要使用不同的后端,您可以设置 Ibis 使用的后端:
>>> ibis.set_backend("duckdb")
>>> ibis.set_backend("polars")
>>> ibis.set_backend("datafusion")
通常,您会创建一个连接对象:
>>> con = ibis.duckdb.connect()
>>> con = ibis.polars.connect()
>>> con = ibis.datafusion.connect()
并且在该后端处理表格:
>>> con.list_tables()
['penguins']
>>> t = con.table("penguins")
您还可以从常见的文件格式如CSV或Apache Parquet中读取:
>>> t = con.read_csv("penguins.csv")
>>> t = con.read_parquet("penguins.parquet")
这允许您通过更改一行代码在本地迭代并在远程部署。
💡查看关于在 DuckDB 和 BigQuery 上使用相同代码的 后端无关数组博客 的一个示例。
2025-03-30(日)