Python数据预处理:使用Dask和Numba并行化加速
如果你善于使用Pandas变换数据、创建特征以及清洗数据等,那么你就能够轻松地使用Dask和Numba并行加速你的工作。单纯从速度上比较,Dask完胜Python,而Numba打败Dask,那么Numba+Dask基本上算是无敌的存在。将数值计算分成Numba sub-function和使用Dask map_partition+apply,而不是使用Pandas。对于100万行数据,使用Pandas方法和混合数值计算创建新特征的速度比使用Numba+Dask方法的速度要慢许多倍。
Python:60.9x | Dask:8.4x | Numba:5.8x |Numba+Dask:1x
作为旧金山大学的一名数据科学硕士,会经常跟数据打交道。使用Apply函数是我用来创建新特征或清理数据的众多技巧之一。现在,我只是一名数据科学家,而不是计算机科学方面的专家,但我是一个喜欢捣鼓并使得代码运行更快的程序员。现在,我将会分享我在并行应用上的经验。
大多Python爱好者可能了解Python实现的全局解释器锁(GIL),GIL会占用计算机中所有的CPU性能。更糟糕的是,我们主要的数据处理包,比如Pandas,很少能实现并行处理代码。
Apply函数vs Multiprocessing.map
Tidyverse已经为处理数据做了一些美好的事情,Plyr是我最喜爱的数据包之一,它允许R语言使用者轻松地并行化他们的数据应用。Hadley Wickham说过:
“plyr是一套处理一组问题的工具:需要把一个大的数据结构分解成一些均匀的数据块,之后对每一数据块应用一个函数,最后将所有结果组合在一起。”
对于Python而言,我希望有类似于plyr这样的数据包可供使用。然而,目前这样的数据包还不存在,但我可以使用并行数据包构成一个简单的解决方案。
Dask
之前在Spark上花费了一些时间,因此当我开始使用Dask时,还是比较容易地掌握其重点内容。Dask被设计成能够在多核CPU上并行处理任务,此外也借鉴了许多Pandas的语法规则。
现在开始本文所举例子。对于最近的数据挑战而言,我试图获取一个外部数据源(包含许多地理编码点),并将其与要分析的一大堆街区相匹配。在计算欧几里得距离的同时,使用最大启发式将最大值分配给一个街区。
最初的apply:
- my_df.apply(lambda x: nearest_street(x.lat,x.lon),axis=1)
Dask apply:
二者看起来很相似,apply核心语句是map_partitions,最后有一个compute()语句。此外,不得不对npartitions初始化。 分区的工作原理就是将Pandas数据帧划分成块,对于我的电脑而言,配置是6核-12线程,我只需告诉它使用的是12分区,Dask就会完成剩下的工作。
接下来,将map_partitions的lambda函数应用于每个分区。由于许多数据处理代码都是独立地运行,所以不必过多地担心这些操作的顺序问题。最后,compute()函数告诉Dask来处理剩余的事情,并把最终计算结果反馈给我。在这里,compute()调用Dask将apply适用于每个分区,并使其并行处理。
由于我通过迭代行来生成一个新队列(特征),而Dask apply只在列上起作用,因此我没有使用Dask apply,以下是Dask程序:
Numba、Numpy和Broadcasting
由于我是根据一些简单的线性运算(基本上是勾股定理)对数据进行分类,所以认为使用类似下面的Python代码会运行得更快一些。
Broadcasting用以描述Numpy中对两个形状不同的矩阵进行数学计算的处理机制。假设我有一个数组,我会通过迭代并逐个变换每个单元格来改变它
相反,我完全可以跳过for循环,并对整个数组执行操作。Numpy与broadcasting混合使用,用来执行元素智能乘积(对位相乘)。
Broadcasting可以实现更多的功能,现在看看骨架代码:
从本质上讲,代码的功能是改变数组。好的一方面是运行很快,甚至能和Dask并行处理速度比较。其次,如果使用的是最基本的Numpy和Python,那么就可以及时编译任何函数。坏的一面在于它只适合Numpy和简单Python语法。我不得不把所有的数值计算从我的函数转换成子函数,但其计算速度会增加得非常快。
将其一起使用
简单地使用map_partition()就可以将Numba函数与Dask结合在一起,如果并行操作和broadcasting能够密切合作以加快运行速度,那么对于大数据集而言,将会看到其运行速度得到大幅提升。
上面的第一张图表明,没有broadcasting的线性计算其表现不佳,并行处理和Dask对速度提升也有效果。此外,可以明显地发现,Dask和Numba组合的性能优于其它方法。
上面的第二张图稍微有些复杂,其横坐标是对行数取对数。从第二张图可以发现,对于1k到10k这样小的数据集,单独使用Numba的性能要比联合使用Numba+Dask的性能更好,尽管在大数据集上Numba+Dask的性能非常好。
优化
为了能够使用Numba编译JIT,我重写了函数以更好地利用broadcasting。之后,重新运行这些函数后发现,平均而言,对于相同的代码,JIT的执行速度大约快了24%。
可以肯定的说,一定有进一步的优化方法使得执行速度更快,但目前没有发现。Dask是一个非常友好的工具,本文使用Dask+Numba实现的最好成果是提升运行速度60倍。
Python数据预处理:使用Dask和Numba并行化加速的更多相关文章
- Python数据预处理:机器学习、人工智能通用技术(1)
Python数据预处理:机器学习.人工智能通用技术 白宁超 2018年12月24日17:28:26 摘要:大数据技术与我们日常生活越来越紧密,要做大数据,首要解决数据问题.原始数据存在大量不完整.不 ...
- python data analysis | python数据预处理(基于scikit-learn模块)
原文:http://www.jianshu.com/p/94516a58314d Dataset transformations| 数据转换 Combining estimators|组合学习器 Fe ...
- python数据预处理for knn
机器学习实战 一书中第20页数据预处理,从文本中解析数据的程序. import numpy as np def dataPreProcessing(fileName): with open(fileN ...
- Python数据预处理—归一化,标准化,正则化
关于数据预处理的几个概念 归一化 (Normalization): 属性缩放到一个指定的最大和最小值(通常是1-0)之间,这可以通过preprocessing.MinMaxScaler类实现. 常用的 ...
- Python数据预处理之清及
使用Pandas进行数据预处理 数据清洗中不是每一步都是必须的,按实际需求操作. 内容目录 1.数据的生成与导入 2.数据信息查看 2.1.查看整体数据信息 2.2.查看数据维度.列名称.数据格式 2 ...
- Python数据预处理(sklearn.preprocessing)—归一化(MinMaxScaler),标准化(StandardScaler),正则化(Normalizer, normalize)
关于数据预处理的几个概念 归一化 (Normalization): 属性缩放到一个指定的最大和最小值(通常是1-0)之间,这可以通过preprocessing.MinMaxScaler类实现. 常 ...
- python数据预处理和特性选择后列的映射
我们在用python进行机器学习建模时,首先需要对数据进行预处理然后进行特征工程,在这些过程中,数据的格式可能会发生变化,前几天我遇到过的问题就是: 对数据进行标准化.归一化.方差过滤的时候数据都从D ...
- Python数据预处理—训练集和测试集数据划分
使用sklearn中的函数可以很方便的将数据划分为trainset 和 testset 该函数为sklearn.cross_validation.train_test_split,用法如下: > ...
- 关系网络数据可视化:2. Python数据预处理
将数据中导演与演员的关系整理出来,得到导演与演员的关系数据,并统计合作次数 import numpy as np import pandas as pd import matplotlib.pyplo ...
随机推荐
- Hive学习笔记七
目录 函数 一.系统自带函数 二.自定义函数 三.自定义UDF函数开发案例 压缩和存储 一.Hadoop源码编译支持Snappy压缩 1.资源准备 2.jar包安装 3.编译源码 二.Hadoop压缩 ...
- coding++:mybatis 嵌套查询子查询column传多个参数描述
mybatis 嵌套查询子查询column传多个参数如下: 2.代码示例 备注:注意,相同颜色的单词都是有关联的 <resultMap id="blogResult" typ ...
- C 2010年笔试题
1 有一个函数, 写一段程序,输入的值,输出的值. #include <stdio.h> void main() { int x,y; printf("输入x:"); ...
- 20175314 实验五 Java网络编程
20175314 实验五 Java网络编程 一.实验报告封面 课程:Java程序设计 班级:1753班 姓名:薛勐 学号:20175314 指导教师:娄嘉鹏 实验日期:2018年5月31日 实验时间: ...
- Ruby学习计划-(0)前言
前言 接触过的编程语言现在来说有C.C++.Java.Object-C.Swift.这几门语言中最熟悉的就是oc了,毕竟靠他吃饭,对于其他几门语言都是初入门径而已,由于本身一直从事iPhone ...
- 别人家的 InfluxDB 实战 + 源码剖析
1. 前几次的分享,我们多次提到了下图中 Metrics 指标监控的 Prometheus.Grafana,而且 get 到了 influxdata 旗下的 InfluxDB 的入门技能. 本次,我们 ...
- python编程学习路线及笔记
话不多说,直接上图! 关于人工智能算法学习思路,欢迎浏览我的另一篇随笔:如果你想开始学习算法,不妨先了解人工智能有哪些方向? 之后博主将持续分享各大算法的学习思路和学习笔记:hello world: ...
- ASP.NET Core技术研究-探秘依赖注入框架
ASP.NET Core在底层内置了一个依赖注入框架,通过依赖注入的方式注册服务.提供服务.依赖注入不仅服务于ASP.NET Core自身,同时也是应用程序的服务提供者. 毫不夸张的说,ASP.NET ...
- Windows上安装Docker
一.下载地址: https://hub.docker.com/editions/community/docker-ce-desktop-windows 二.安装直接下一步下一步就好了 具体可看: ht ...
- gdb调试工具常用命令 && kdb
编译程序时需要加上-g,之后才能用gdb进行调试:gcc -g main.c -o main gdb中命令: 回车键:重复上一命令 (gdb)help:查看命令帮助,具体命令查询在gdb中输入help ...