前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >放弃“for循环”,教你用这种算法 !(附代码)

放弃“for循环”,教你用这种算法 !(附代码)

作者头像
数据派THU
发布2018-01-29 19:34:24
1.2K0
发布2018-01-29 19:34:24
举报
文章被收录于专栏:数据派THU数据派THU

原文标题:Why you should forget ‘for-loop’ for data science code and embrace vectorization

作者:Tirthajyoti Sarkar

翻译:杨金鸿

校对:丁楠雅

本文长度为1986字,建议阅读5分钟

数据科学需要快速计算和数据转换的能力。Python中的NumPy对象提供了优于常规编程结构算法,比如for循环。如何用简单的代码来演示它呢?

在11月27日至12月3日的KDnugget网站上,这篇文章被转载最多(https://www.kdnuggets.com/2017/12/top-news-week-1127-1203.html)。

我们使用for循环来完成大部分工作,这些工作需要对一长串的元素进行更新。我敢断言,几乎所有人阅读这篇文章的读者,在他们高中或大学里都里有肯定有使用过for循环语句编写自己的第一个矩阵或矢量乘法代码。for循环为编程社区提供了长期稳定的服务。

然而,for循环在处理大型数据集时执行速度通常较慢(例如:在大数据时代处理几百万条记录)。对于像Python这样的解释性语言来说尤其如此。如果您的循环体很简单,那么循环解释器会占用大量的开销。

幸运的是,大部分主流的编程语言都有另外一种编程语言可以取代它。Python也是如此。

Numpy是Numerical Python(http://numpy.org/)的简称,同时也是Python生态系统中高性能科学计算和数据分析所需要的基本包。它几乎是所有高级语言工具的基础,如Pandas和 scikit-learn都是在Numpy的基础上编译的。TensorFlow使用NumPy阵列作为底层编译块。在这之上构建了Tensor对象和用于深度学习的graphflow(使用了大量的线性代数运算在一个长的列表/矢量/矩阵)。

Numpy提供的两个最重要的特性是:

  • Ndarray:一个快速空间高效的多维数组,提供了矢量化计算操作和复杂的广播能力(https://towardsdatascience.com/two-cool-features-of-python-numpy-mutating-by-slicing-and-broadcasting-3b0b86e8b4c7)
  • 标准的数学函数,可以在不写循环的情况下,对整个数据数组进行快速操作。

在数据科学、机器学习和Python社区中,您经常会遇到这样的断言:Numpy是更速度的。因为它是基于矢量的实现,而且它的许多核心例程都是用C语言编写(基于CPython 框架:https://en.wikipedia.org/wiki/CPython)。

这篇文章是一个CPython 框架的很好阐述(http://notes-on-cython.readthedocs.io/en/latest/std_dev.html)Numpy可以与各个方面协同工作。甚至可以使用Numpy api编写裸机骨C例程。Numpy阵列是均匀类型的密集阵列。相反,Python列表是指向对象的指针数组,即使它们是相同的对象类型。你可以从区域性关联(https://en.wikipedia.org/wiki/Locality_of_reference)得到收获。

许多Numpy操作是用C语言实现的,避免了Python中循环的开销、指针指向每个元素的动态类型检查(https://www.sitepoint.com/typing-versus-dynamic-typing/)。Numpy速度的提升取决于你所执行的操作。对于数据科学和现代机器学习来说,这是一个非常宝贵的优势,因为通常数据集的大小会达到数百万甚至数十亿。并且您不希望使用For循环和它的相关的算法进行更新。

如何用一个中等大小的数据集来验证它呢?

这里是Jupyter Github代码链接(https://github.com/tirthajyoti/PythonMachineLearning/blob/master/How%20fast%20are%20NumPy%20ops.ipynb)。其中在一些简单的代码行中,Numpy的操作速度与常规Python编程的速度不同,比如for循环、map-function(https://stackoverflow.com/questions/10973766/understanding-the-map-function)或list-comprehension(http://www.pythonforbeginners.com/basics/list-comprehensions-in-python)。

这里我简单的概括下基本流程:

  • 创建一个中等数量集的浮点数列表,最好是从连续的统计分布中抽取出来,比如高斯分布或均匀随机分布。为了演示我选择了100万条数据
  • 在列表中创建一个ndarray对象,也就是矢量化
  • 编写简短的代码块来更新列表,并在列表上使用数学运算,比如以10为底的对数。使用for循环、map-function和list-comprehension。并使用time()函数来核实处理100万条数据需要花费多长时间

t1=time.time()for item in l1: l2.append(lg10(item))t2 = time.time()print("With for loop and appending it took {} seconds".format(t2-t1))speed.append(t2-t1)

  • 用Numpy的内置数学方法(np.log10)在ndarray对象上做同样的操作。计算出花费了多长时间

t1=time.time()a2=np.log10(a1)t2 = time.time()print("With direct Numpy log10 method it took {} seconds".format(t2-t1))speed.append(t2-t1)

  • 在一个列表中存储执行时间,并绘制出一个差异的柱状图

下面是结果显示。你可以运行Jupyter笔记本上的所有代码单元块来重复整个过程。每次它会生成一组新的随机数,因此精准的执行时间可能会有所不同。但总体来说,趋势始终是相同的。您可以尝试使用各种其他的数学函数/字符串操作或者集合,来检查是否适用于一般情况。

这里有一个由法国神经科学研究员编写的完整开源在线书籍(https://www.labri.fr/perso/nrougier/from-python-to-numpy/#id7)。

简单数学运算比较速度的柱状图

如果你有任何问题或想法要分享,请与作者联系(tirthajyoti@gmail.com)。您也可以在Python、R或MATLAB和机器学习资源中查看作者的GitHub库(https://github.com/tirthajyoti),获得其他有趣的代码片段。你也可以在LinkedIn(https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)上关注我。

原文链接:

https://towardsdatascience.com/why-you-should-forget-for-loop-for-data-science-code-and-embrace-vectorization-696632622d5f

杨金鸿,北京护航科技有限公司员工,在业余时间喜欢翻译一些技术文档。喜欢阅读有关数据挖掘、数据库之类的书,学习java语言编程等,希望能在数据派平台上熟识更多爱好相同的伙伴,今后能在数据科学的道路上走的更远,飞的更远。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-12-21,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 数据派THU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com