处理超大型数据的17个策略
原文出处:Medium
作者:Jeff Hale
原文标题:17 Strategies for Dealing with Data, Big Data, and Even Bigger Data
处理大数据很棘手。没有人喜欢内存不足的错误,没有人喜欢等待代码长时间运行,没有人喜欢离开Python。
Python是数据科学领域最流行的语言,Numpy和Pandas是进行数值计算和数据分析的主要工具。
不幸的是,如果你在本地工作,pandas可以处理的数据量受计算机内存的限制。如果你在云端工作,更多的内存会花费更多的钱。
不管你的代码在哪里运行,你都希望操作能快速发生,这样你就可以完成任务。
在本文中,我将提供一些技巧,并介绍强大的工具(三方库),以帮助您使用Python高效地处理大数据。
基础原则
如果您曾经听到或看到过关于加速代码的建议,那么您已经看到了警告:不要过早优化!这是个好建议。但了解技术也很重要,这样你就可以在一开始就编写干净快速的代码。
对于任何大小的数据集,都建议采用以下3个策略:
- 尽可能避免嵌套循环。循环嵌套会导致计算时间呈多项式增长,如果您有多个项目要搜索,将等待一段时间。
- 在Python中尽可能使用列表推导。与按需加载列表时重复加载列表的响应相比,创建溢出列表的速度更快。但是,一般来说,不要为了速度而牺牲代码可读性,所以要小心使用嵌套列表推导。
- 在pandas中,使用内置的矢量化函数,其原理与列表推导相似。一次将一个函数应用于整个数据结构要比反复调用一个函数快得多。
如果你想使用apply,想想是否真的需要。apply会遍历每一行或每一列上的所有元素,矢量化方法通常速度更快,代码更少,因此它们在多个方面都是成功的。
同样,避免其他在Series和DataFrame上循环的方法,例如applymap,itterrows,itrtuples. 如果可以,使用map或replace,以节省大量时间。
请注意,这些建议可能不适用于非常少量的数据,但在这种情况下,风险很小,所以谁在乎呢。
最重要的原则
如果能使用pandas,就不要使用其它工具
如果你没有遇到计算速度和内存占用的问题,就应该一直使用pandas,且不用担心这些问题。
但总有一天你会遇到一个大数据集,然后你会想该怎么做。让我们看看一些有效的策略。
处理大数据的策略(约几百万行)
- 如果您正在进行机器学习,请使用您的数据子集来探索、清理并创建一个基线模型。快速解决90%的问题,节省时间和资源。这项技术可以帮助你更快地得到一个好的模型!
- 用pandas加载数据时使用usecols参数,仅仅加载需要的数据,更少的数据=胜利。
- 有效地使用数据类型。将数值列下放到最小的数据类型中,将基数较低(只有几个值)的列转换为分类数据类型。
- 使用scikit-learn训练模式时尽可能使用更多的处理核心。默认情况下,scikit learn只使用计算机的一个核。许多计算机有4个或更多的核。
- 将pandas数据框保存为feather或pickle格式,以便更快地读写。
- 使用pd.eval加快运算速度,以字符串形式传递代码。这里有一个简单的测试,数据框有100列。
Pandas在底层调用numexpr,numexpr也可以和NumPy一起工作。克里斯·康兰的《Fast Python》是学习如何加快Python代码速度的极好读物。
处理超大数据的策略(约几千万行)
-
使用numba。如果你在进行数学计算,Numba会给你一个很大的速度提升。安装numba并导入。然后使用@numba.jit当需要在NumPy阵列上循环且不能使用向量化方法时,使用decorator函数。它仅适用于numpy数组。对pandas数据框架使用.to_numpy()将其转换为numpy数组。
-
在合适的条件下使用SciPy-sparse矩阵。Scikit learn使用一些变换器(如计数器)自动输出稀疏阵列。当数据大部分为0或缺少值时,可以将列转换为pandas的零散数据类型。
-
使用Dask以并行化的方式读取数据并输出到pandas。Dask还可以跨多台机器并行化数据操作。它模仿了pandas和numpy API的一个子集。Dask-ML是跨多台机器并行化机器学习算法的姊妹包。它模拟了scikit-learn的API。Dask与其他受欢迎的机器学习库(如XGBoost、LightGBM、PyTorch和TensorFlow)配合良好。
-
使用带或不带GPU的PyTorch。在GPU上使用PyTorch可以获得非常大的加速,正如我在这篇关于排序的文章中所发现的。
值得关注的大数据处理工具
截至2020年年中,以下三个工具处于领先地位。如果您在本地使用一个CPU,这些包不太可能满足您的需要。但这些都很有前景,值得关注。
-
你能使用大量的中央处理器核心么?贵公司的数据是否有超过32列?如果是考虑Modin。它模拟了pandas库的一个子集,以加快对大型数据集的操作。它在底层使用apache arrow(via Ray)或Dask。Dask后端是实验性的。在我的测试中,有些地方速度不快,例如从NumPy数组中读取数据的速度很慢,内存管理也是一个问题。
-
使用jax代替NumPy。Jax是一个开源的谷歌产品,是最具优势的。它通过在底层使用五个东西来加速操作:autograd、XLA、JIT、vectorizer和parallelizer。Jax在单个CPU、GPU或TPU上工作,可能比使用PyTorch或TensorFlow获得提速更简单。Jax也有利于深度学习。到2020年中期,它可以与numpy整合,但不能与pandas整合。然而,您可以将一个数据框架转换为TensorFlow或NumPy对象,然后使用jax。
-
Rapids cuDF在GPU上使用Apache arrow和类似pandas的API。这是来自NVIDIA的开源Python包。Rapids与Dask配合得很好,因此可以获得多个并行处理数据的GPU。对于最大的工作负载,这将提供一个很好的提升。
你们的点赞和收藏是我们最大的创作动力,我们每天都会为大家带来数据科学和量化交易领域的精品内容。
蜂鸟数据:开源金融数据接口,一个API连接世界金融市场。
蜂鸟数据团队由业界顶尖的数据工程师,数据科学家和宽客组成,我们正努力构建一个开源的金融数据库,并提供API接口,目标是令金融数据开源化和平民化。
浏览并测试我们接口吧,目前覆盖股票,外汇,商品期货,数字货币和宏观经济领域,包括实时报价(tick)和历史数据(分钟),提供REST API和Websocket两种接入方式,能够满足金融分析师,量化交易和理财app的需求。