![665db36badf0a4f32f377c72723019aa.png](https://img-blog.csdnimg.cn/img_convert/665db36badf0a4f32f377c72723019aa.png)
Why DuckDB系列:
- Why DuckDB
- Python单机查询1.5亿行数据秒出
- DuckDB批量转CSV为Parquet
- DuckDB FDW 来了(敬请期待)
昨天介绍了Why DuckDB,今天就用它来体验在Python下1.5亿行数据的查询。
数据
最早知道 AirOnTime87to12 是学Sparklyr的时候看到一篇文章,使用Sparklyr导入30GB数据[1],具体文章内容,有兴趣的自己看,这里就不展开了。
AirOnTime87to12是一份航线准点率( On-time performance,OTP)的压缩包:
- 303 个CSV,大小30G
- 148617414 行数据,29个变量
- Zip压缩包4.2G
- 2013年8月由http://transtats.bts.gov提供下载
- 转为snappy压缩的parquet 2.4G
硬件环境
- OS:MacOS 10.15.6 (19G2021)
- CPU:2.8 GHz Quad-Core Intel Core i7
- MEM:16 GB 1600 MHz DDR3
- HD:1T SSD
Python
- Python 3.7
- Jupyter-Lab
- DuckDB GitHub Master
$ git clone https://github.com/cwida/duckdb
$ cd duckdb
$ BUILD_PYTHON=1 make
注:通过pip install duckdb 或者conda install python-duckdb 安装的版本暂时不支持通配符。
体验
- 创建duckdb链接,本例使用内存数据库
%load_ext autotime
import duckdb
db = duckdb.connect(":memory:")
duck_cursor = db.cursor()
def fetchdf(sql):
return duck_cursor.execute(sql).fetchdf();
- 创建airontime视图
sql = """create or replace view airontime as
select *
from parquet_scan('/data/AirOnTime/*.parquet');
"""
fetchdf(sql)
- 先看看多少行
fetchdf("select count(*) from airontime")
![ff4315b9d2446b8b44018df7c57e6312.png](https://img-blog.csdnimg.cn/img_convert/ff4315b9d2446b8b44018df7c57e6312.png)
![c38e927c70bf2b23c1399d622fc0c2e4.png](https://img-blog.csdnimg.cn/img_convert/c38e927c70bf2b23c1399d622fc0c2e4.png)
- 对比下PySpark 3.0(500多ms)
![e1423ee7023ac197506f5ceebcf7479e.png](https://img-blog.csdnimg.cn/img_convert/e1423ee7023ac197506f5ceebcf7479e.png)
- 体验下聚合查询(如果没有oder by, 在2s以内)
sql ='''
select "YEAR" , count(*)
from airontime ap
group by 1
order by 1;
'''
fetchdf(sql)
![b1ba4ff845add24019971f9745b0e19a.png](https://img-blog.csdnimg.cn/img_convert/b1ba4ff845add24019971f9745b0e19a.png)
- 读取csv
支持csv和csv.gz, UTF8编码,分隔符,换行符,是否有header,以及变量数据类型都可以尝试让duckdb自己来判断
sql ="""
select * f
rom read_csv_auto('/Users/steven/data/iris.csv')
"""
iris=fetchdf(sql)
type(iris) # pandas.core.frame.DataFrame
iris.dtypes
![ca4e5c964bc74536d058a9ef1297706f.png](https://img-blog.csdnimg.cn/img_convert/ca4e5c964bc74536d058a9ef1297706f.png)
- 通过SQL语句访问Pandas DataFrame
#把DataFrame iris 映射为虚拟表iris,然后使用SQL来查询
duckdb.query(iris,'iris',
"select * from iris limit 5").fetch_df()
![61b70a1ab69590aa6bf902039a4c8b94.png](https://img-blog.csdnimg.cn/img_convert/61b70a1ab69590aa6bf902039a4c8b94.png)
- 查询结果 导出为Parquet 或者csv
duckdb.query(iris,'iris',
"""copy(select * from iris limit 5)
to 'iris_5.parquet' (format 'parquet')""").fetch_df()
duckdb.query(iris,'iris',
"""copy(select * from iris limit 5)
to 'iris_5.csv' (format 'csv')""").fetch_df()
- 关闭连接
duck_cursor.close()
db.close()
其它更多惊艳功能等待你来挖掘,有兴趣的可以安装DuckDB体验起来。
参考
- https://www.brodrigues.co/blog/2018-02-16-importing_30gb_of_data/
- https://docs.microsoft.com/en-us/machine-learning-server/r-reference/revoscaler/airontime87to12
- https://github.com/cwida/duckdb