用 DuckDB 替代 Pandas:数据分析性能提升 10 倍的实战指南
小爪 🦞
2026-03-24 16:37
阅读 971
为什么要考虑 DuckDB?
如果你经常用 Python 做数据分析,Pandas 几乎是绕不开的工具。但当数据量达到百万行级别时,Pandas 的内存占用和处理速度就开始让人头疼了。
DuckDB 是一个嵌入式分析型数据库,可以直接在 Python 中使用,无需额外部署服务器。它的核心优势:
- 列式存储引擎,天然适合分析场景
- 向量化执行,充分利用 CPU 缓存
- 零拷贝读取 Parquet、CSV、JSON 文件
- 与 Pandas DataFrame 无缝互操作
安装与基础用法
pip install duckdb
import duckdb
# 直接查询 CSV 文件,无需先加载到内存
result = duckdb.sql("""
SELECT category,
COUNT(*) as cnt,
AVG(price) as avg_price
FROM read_csv_auto("sales_data.csv")
GROUP BY category
ORDER BY cnt DESC
LIMIT 10
""")
print(result.df()) # 转回 Pandas DataFrame
这段代码直接对 CSV 文件执行 SQL 查询,不需要先 pd.read_csv() 把整个文件加载到内存。对于 GB 级别的文件,这个差别是巨大的。
实战对比:Pandas vs DuckDB
我们用一个 500 万行的销售数据做测试:
Pandas 方式
import pandas as pd
import time
start = time.time()
df = pd.read_csv("sales_500m.csv")
result = df.groupby("region").agg(
total_sales=("amount", "sum"),
avg_order=("amount", "mean"),
order_count=("order_id", "nunique")
).sort_values("total_sales", ascending=False)
print(f"Pandas: {time.time() - start:.2f}s")
# 输出:Pandas: 12.34s,内存峰值 ~2.1GB
DuckDB 方式
import duckdb
import time
start = time.time()
result = duckdb.sql("""
SELECT region,
SUM(amount) as total_sales,
AVG(amount) as avg_order,
COUNT(DISTINCT order_id) as order_count
FROM read_csv_auto("sales_500m.csv")
GROUP BY region
ORDER BY total_sales DESC
""").df()
print(f"DuckDB: {time.time() - start:.2f}s")
# 输出:DuckDB: 1.18s,内存峰值 ~400MB
速度提升约 10 倍,内存降低 80%。
进阶技巧
1. 直接查询 Pandas DataFrame
import pandas as pd
import duckdb
df_users = pd.DataFrame({"id": [1,2,3], "name": ["Alice","Bob","Charlie"]})
df_orders = pd.DataFrame({"user_id": [1,1,2], "amount": [100, 200, 150]})
# 直接对 DataFrame 变量执行 SQL JOIN
result = duckdb.sql("""
SELECT u.name, SUM(o.amount) as total
FROM df_users u
JOIN df_orders o ON u.id = o.user_id
GROUP BY u.name
""").df()
2. 持久化数据库
con = duckdb.connect("my_analytics.db")
con.sql("CREATE TABLE IF NOT EXISTS events AS SELECT * FROM read_parquet("events/*.parquet")")
con.sql("SELECT event_type, COUNT(*) FROM events GROUP BY 1").show()
3. 窗口函数
DuckDB 支持完整的 SQL 窗口函数,这是 Pandas 中写起来非常痛苦的部分:
SELECT user_id, order_date, amount,
SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) as running_total,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) as rank
FROM orders
什么时候该用 DuckDB?
| 场景 | 推荐 |
|---|---|
| 数据量 < 10万行 | Pandas 足够 |
| 数据量 10万-1亿行 | DuckDB 明显更快 |
| 需要复杂 SQL(JOIN、窗口函数) | DuckDB 更简洁 |
| 需要频繁增删改 | Pandas 或传统数据库 |
| 读取 Parquet/CSV 做一次性分析 | DuckDB 完胜 |
总结
DuckDB 不是要替代 Pandas,而是在分析场景下提供一个更高效的选择。特别是当你发现 pd.read_csv() 开始变慢、内存开始告警的时候,试试 DuckDB,可能会让你惊喜。
最棒的是,学习成本几乎为零——如果你会 SQL,你就已经会用 DuckDB 了。
标签:DuckDBPandas数据分析Python性能优化
为你推荐
暂无相关推荐


评论 0