文章目录
Pandas可谓是目前数据分析最便捷的工具,但是当数据规模变大时,其“将数据加载到内存中”的特性成为了其弱点。虽然有一些方式可以一定程度上使得其能够处理大规模的数据,但是这些操作都是治标不治本。SQL自上世纪七十年代以来不断被优化,支持大规模增删改查数据。因此SQL是大规模数据分析的一把利剑。
pandas与sql的性能分析
背景
数据库中有百万条记录,每条记录分为三列:用户id,用户名及是否激活。表占据了87M的磁盘空间。
样本如下
1 | postgres=# select * from users; |
导出所有数据再转为DataFrame
Python程序如下
1 | # load_all_then_convert.py |
性能分析如下
1 | JinlongLi (master *) mine_rpn $ python load_all_then_convert.py |
从profiling结果可以看出
- 导入profile库耗费
40.1M
内存;导入Pandas库耗费31.1M
内存; - 从数据库中取数据,转化为
Pandas.DataFrame
耗费~300M
内存。
移除profile工具占用的内存,则一共占据330M
内存(峰值)。数据在表中占据87M的空间。
导出指定数据列再转为DataFrame
如果不是导出所有的列,而是感兴趣的指定列,性能如何?
1 | JinlongLi (master *) mine_rpn $ python load_specified_cols.py |
不导出数据,数据库中做分析
如果在不将数据导出,而直接在数据库中做聚合操作,性能表现如何呢?
1 | JinlongLi (master *) mine_rpn $ python agg_in_db.py |
可以看到,移除profile
工具占用的内存,整个程序一共耗费34M
的内存。与之前的方式相比,这种方式大大降低了内存占用。
结果对比表
项目 | 内存(M) | 内存-移除pandas(M) | 耗时(s) |
---|---|---|---|
导出整张表 | 330 | 300 | 3.6 |
导出指定列 | 188 | 157 | 3.2 |
在数据库中做聚合操作,导出结果 | 34 | 2.4 | 2.4 |
可以看出pandas
处理百万行三列数据耗费内存0.3G,而利用SQL来执行分析运算,将其内存占用降低了百倍。
SQL替换Pandas
描述性统计
- 如何用pandas实现一些pandas提供的功能描述性统计(descriptive statistics)
pandas:数值Series
1 | >>> s = pd.Series([1, 2, 3]) |
sql
1 | SELECT |
pandas:类别Series
1 | >>> s = pd.Series(['a', 'a', 'b', 'c']) |
sql
1 | SELECT |
填充缺失值
常量填充
pandas:
1 | >>> import pandas as pd |
sql
1 | SELECT |
coalesce
: 接收任意个参数,返回第一个非NULL的参数
前、后向填充
1 | WITH tb AS ( |