Python技术迷

Arrow + DuckDB,完爆 Pandas!

哎兄弟,昨晚快十一点我还在公司楼下抽烟,结果我们组小李那小子非要问我:东哥你用Pandas处理大数据烦不烦?我说烦啊,一堆内存不够用,慢得一批。后来他说现在不是都用Arrow+DuckDB了吗,问我体验咋样。唉,这话题我就忍不住了——你们是不是也被Pandas那个慢、OOM气过啊?尤其那种几十G的csv,Pandas直接给你整个python干崩溃。

Arrow+DuckDB,真的是“暴打”Pandas

你别说,这俩哥们组合起来,那叫一个爽。先说下场景,上次我处理一个电商日志,压缩包都20多G,我用Pandas读,电脑直接风扇响到像开了飞机,最后还死机...后来小李教我Arrow和DuckDB,真的省心太多了。

你想啊,Pandas不是老是占满内存吗?Arrow这玩意就不一样,它数据是列式存储,还可以零拷贝和持久化存到磁盘上,效率嘎嘎高。DuckDB又有点像数据库和Pandas的结合体,支持SQL直接查Arrow对象,还能当临时分析库用,你数据太大分分钟给你落盘。关键语法还和SQL一样,啥join、group by直接查。

就昨天的那个日志,原本pandas得这么来:

import pandas as pd

df = pd.read_csv('logs.csv')
# 假如你要统计下每个用户的访问量
result = df.groupby('user_id')['url'].count()

上面这样,文件大点直接卡死。换Arrow+DuckDB,完全不是一个体验:

import duckdb
import pyarrow as pa
import pyarrow.csv as csv

# 直接流式读,根本不担心内存爆炸
arrow_table = csv.read_csv('logs.csv')
con = duckdb.connect()
con.register('logs', arrow_table)
# 直接写SQL
result = con.execute("SELECT user_id, count(url) FROM logs GROUP BY user_id").fetch_arrow_table()

我上次跑2亿行日志,几分钟就出了结果,内存占用一直很稳。Pandas那个基本都撑不住。

再来个复杂一点的,你要多表join

你别说,有时候一个用户表、一个日志表,要搞个大join,Pandas得写一堆merge,慢到怀疑人生。而DuckDB+Arrow你直接一行SQL:

user_table = csv.read_csv('users.csv')
con.register('users', user_table)

query = """
    SELECT u.user_name, count(l.url)
    FROM logs l
    JOIN users u ON l.user_id = u.user_id
    GROUP BY u.user_name
"""

result = con.execute(query).fetch_arrow_table()

这SQL直接飞起,甚至比你MySQL本地查还快,因为Arrow内存布局天然适合分析型计算。

Arrow的细节你得会点

我头两次用Arrow还纳闷,怎么不像Pandas那样直接df.head(),其实Arrow Table和Pandas DataFrame不太一样。你得这么写:

# Arrow Table 转 Pandas
df = arrow_table.to_pandas()

不过很多时候都不用转,DuckDB直接支持Arrow Table查询,内存不会炸。

有兄弟问我,Arrow+DuckDB是不是啥格式都能吃?不是啊,得csv、parquet那种结构化文件,json那种半结构化的还得你自己先规整下。还有就是,DuckDB虽然很快,但多线程不是很激进(相对ClickHouse那种)。不过对一般个人分析,真的够用了。

你只要碰到

  • 本地数据大,Pandas爆内存
  • 需要SQL那种灵活操作(join/group by/聚合啥的)
  • 多格式数据混用 就可以用Arrow+DuckDB。特别是那种用Pandas死活读不下的数据,用这套组合你会觉得自己像换了台新电脑。

-END-

我为大家打造了一份RPA教程,完全免费:https://www.songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领