纽比广播

如果不受内存限制,优化numpy中嵌套循环的第一步是使用广播并以矢量化的方式执行操作:import numpy as np

def mb_r(forecasted_array, observed_array):

"""Returns the Mielke-Berry R value."""

assert len(observed_array) == len(forecasted_array)

total = np.abs(forecasted_array[:, np.newaxis] - observed_array).sum() # Broadcasting

return 1 - (mae(forecasted_array, observed_array) * forecasted_array.size ** 2 / total[0])

但在这种情况下,循环是用C而不是Python进行的,它涉及到一个大小(N,N)数组的分配。在

广播不是灵丹妙药,试着打开内环

如上所述,广播意味着巨大的内存开销。所以它应该小心使用,而且它并不总是正确的方法。虽然你的第一印象可能是在任何地方使用它-不要。不久前我也被这个事实搞糊涂了,看我的问题Numpy ufuncs speed vs for loop speed。为了不太冗长,我将在您的示例中显示这一点:

^{pr2}$

小型阵列(广播更快)forecasted = np.random.rand(100)

observed = np.random.rand(100)

%timeit mb_r_bcast(forecasted, observed)

57.5 µs ± 359 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit mb_r_unroll(forecasted, observed)

1.17 ms ± 2.53 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

中型阵列(相等)forecasted = np.random.rand(1000)

observed = np.random.rand(1000)

%timeit mb_r_bcast(forecasted, observed)

15.6 ms ± 208 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit mb_r_unroll(forecasted, observed)

16.4 ms ± 13.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

大尺寸阵列(广播速度较慢)forecasted = np.random.rand(10000)

observed = np.random.rand(10000)

%timeit mb_r_bcast(forecasted, observed)

1.51 s ± 18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit mb_r_unroll(forecasted, observed)

377 ms ± 994 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

正如您可以看到的,对于小型阵列,广播版本比展开的快20倍,对于中型阵列,它们是而不是相等,但对于大型阵列,它的速度4倍,因为内存开销要付出高昂的代价。在

Numba jit与并行化

另一种方法是使用numba及其强大的@jit函数修饰符。在这种情况下,只需对初始代码稍作修改。另外,为了使循环并行,您应该将range更改为prange,并提供parallel=True关键字参数。在下面的代码片段中,我使用了与@jit(nopython=True)相同的@njit修饰符:from numba import njit, prange

@njit(parallel=True)

def mb_r_njit(forecasted_array, observed_array):

"""Returns the Mielke-Berry R value."""

assert len(observed_array) == len(forecasted_array)

total = 0.

size = len(forecasted_array)

for i in prange(size):

observed = observed_array[i]

for j in prange(size):

total += abs(forecasted_array[j] - observed)

return 1 - (mae(forecasted_array, observed_array) * size ** 2 / total)

您没有提供mae函数,但是要在njit模式下运行代码,还必须修饰mae函数,或者如果它是一个数字,则将其作为一个参数传递给jitted函数。在

其他选项

Python的科学生态系统是巨大的,我只是提到了其他一些可以加速的选项:Cython,Nuitka,Pythran,bottleneck等等。也许你对gpu computing感兴趣,但这实际上是另一个故事。在

时间安排

不幸的是,在我的电脑上,时间安排是:import numpy as np

import numexpr as ne

forecasted_array = np.random.rand(10000)

observed_array = np.random.rand(10000)

初始版本%timeit mb_r(forecasted_array, observed_array)

23.4 s ± 430 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

numexpr%%timeit

forecasted_array2d = forecasted_array[:, np.newaxis]

ne.evaluate('sum(abs(forecasted_array2d - observed_array))')[()]

784 ms ± 11.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

广播版%timeit mb_r_bcast(forecasted, observed)

1.47 s ± 4.13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

内部循环展开版本%timeit mb_r_unroll(forecasted, observed)

389 ms ± 11.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

numbanjit(parallel=True)版本%timeit mb_r_njit(forecasted_array, observed_array)

32 ms ± 4.05 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

可以看出,njit方法比初始解决方案快730倍,也比numexpr解决方案快24.5倍(也许你需要英特尔的矢量数学库来加速)。同样,与初始版本相比,内部循环展开的简单方法可以使60x加速。我的规格是:

Intel(R)Core(TM)2四CPU Q9550 2.83GHz

Python 3.6.3

数字1.13.3

数字0.36.1

numexpr 2.6.4

最后说明

很奇怪,这是一个非常缓慢的测试arr = np.arange(1000)

ls = arr.tolistist()

%timeit for i in arr: pass

69.5 µs ± 282 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit for i in ls: pass

13.3 µs ± 81.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit for i in range(len(arr)): arr[i]

167 µs ± 997 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit for i in range(len(ls)): ls[i]

90.8 µs ± 1.07 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

结果证明你是对的。迭代列表的速度2-5x。当然,这些结果必须带有一定的讽刺意味:)

python双层for循环优化,如何优化Python中的嵌套for循环相关推荐

  1. java的循环控制结构有哪些_java中的控制结构(if,循环)详解

    1 说明JAVA语言中三种控制循环结构的代码形式(其他 1. while(condition){ statements; } 其中,condition是任何布尔表达式,其返回值为true 或 fals ...

  2. c语言内外循环的标志,考驾照中的空气内循环标志

    1 灯光开关在该位置时,前雾灯点亮.查看本题分析 2 属于申请增加准驾车型的,应当收回原机动车驾驶证.查看本题分析 3 驾驶机动车在这种信号灯亮的路口,可以右转弯.查看本题分析 4 驾驶机动车在路口遇 ...

  3. python的def语句例题_下列 Python语句的输出结果是?

    [单选题]Python语句序列"x='car';y=2; print(x+y)"的输出结果是 [填空题]Pyhon语句序列"s1= 'red hat'; print(s1 ...

  4. 在下列选项中不属于python特点的是_在下列选项中,不属于 Python特点的是( )。_学小易找答案...

    [填空题]在 Python无穷循环 while True:的循环体中可以使用( )语句退出循环 [填空题]下列 Python语句的输出结果是 counter=1 num= 0 def Testvari ...

  5. c语言空循环的作用是什么意思,C语言空循环和无穷循环有的区别

    跟大家普及下空循环和无穷循环的概念,空循环并不会无休止地进行下去–在重复预先指定的次数后,它就会退出循环.无穷循环会无休止地进行下去,并且永远不会退出循环.把空循环和无穷循环对比一下,就能很好地说明它 ...

  6. java中的if for循环语句怎么写_for语句用法-if语句的用法-while语句用法

    Java中的for语句的用法 格式: for (initialization;condition;increment)statement; 其中: initialization是for循环的初始部分, ...

  7. java双重for循环流程图_JAVA程序逻辑中的循环结构

    在上一篇文章中提到了程序逻辑通过顺序.分支.循环三种结构来实现的,并介绍了分支结构的执行语句,那么今天这篇文章介绍实现程序逻辑的另一种结构--循环结构. 什么是循环结构 循环结构是指在程序设计语言中按 ...

  8. “好串”求解算法优化原理与Python实现

    佩服国防科大刘万伟老师的数学功底与编码功底,感谢刘老师无私分享! =====正文======= 题目要求:称一个 0-1 串是"好串",如果它的任何子串不在其中连续出现三次以上.编 ...

  9. python转c工具shedskin_shedskin— 一种python性能优化工具 | 学步园

    虽说python的性能在脚本语言中还算杰出,但是当程序中出现for,while循环或者函数递归调用的情况,其性能就下降的非常快. 比如,用递归方法计算fibonacci(33) ,C语言只要几毫秒,但 ...

最新文章

  1. PHP安装parsekit扩展查看opcode
  2. CVPR2021单目深度估计:腾讯光影研究室优势夺冠,成果落地应用
  3. java 运算顺序 从左到右_java – 表达式与运算符优先级的从左到右的评估.为什么从左到右的评估似乎胜出了?...
  4. AI A_star算法野人渡河-实验报告
  5. buu [BJDCTF 2020]这是base??
  6. PC 远程控制 android手机的方法之一VNC
  7. pdf转换成可在线浏览的电子杂志zmaker_pdf
  8. C++版 - 剑指offer面试题38:数字在已排序数组中出现的次数
  9. 二元隐函数求二阶偏导_在线计算专题(03):具体、抽象函数的导数、微分与方向导数的计算...
  10. java开发一款模拟写字板系统
  11. 浅谈String str = 和 new String()的区别
  12. 解决IIS无法启动w3svc
  13. 中文字符频率统计python_使用 Python 统计中文字符的数量
  14. mybatisPlus代码自动生成
  15. gephi java教程_Gephi教程汇总
  16. kubernetes核心组件的运行机制
  17. css表格做日历,CSS 制作有弹性的日历表
  18. 调用python-nmap实现扫描局域网存活主机
  19. 微信小游戏是个人尝试做游戏最好的选择
  20. LIO-SAM回环检测模块代码解析

热门文章

  1. XSS攻击及解决方案
  2. Activiti的ProcessEngine的基本配置
  3. python程序出现了异常会执行哪个语句,python中的异常是什么?应该怎么处理异常?...
  4. java 集群会话管理_架构设计之Spring-Session分布式集群会话管理
  5. thymeleaf引用html_SpringBoot+Thymeleaf实现html文件引入(类似include功能)_html/css_WEB-ITnose...
  6. 多目标进化优化 郑金华pdf_简化审批流程 金华首张以“告知承诺制”审批的医疗器械经营许可证发放...
  7. php web服务器部署,php – 如何配置apache web服务器以部署laravel 5
  8. utc转换成时间 mysql_在select语句中将Datetime列从UTC转换为本地时间
  9. java正则表达式所有字符串_“JAVA”正则表达式如何匹配所有符合要求的子字符串?...
  10. apollo编译源码使用并将eureka替换为自己的eureka服务