Numpy向量操作的并行化

Numpy向量操作的并行化

NumPy是一个包含多维数组对象以及数组处理程序集合的库。正如你所知道的,它并不进行并行操作,但是并行执行操作可以为我们提供很大的性能优势。我们将使用numexpr库来实现NumPy的并行操作。

NumExpr

NumExpr是NumPy的一个快速数字表达式评估器。作用于数组的表达式,如3a+4b(其中a和b是数组),用它可以加速,并且比在Python中进行时占用的内存更少。此外,它的多线程能力可以利用所有的核心,与NumPy相比,性能有了显著的提升。

为了我们的需要,我们将使用numexpr包中的evaluate函数。

语法: numexpr.evaluate(ex, local_dict=None, global_dict=None, out=None, order=’K’, casting=’safe’, **kwargs)

参数:

  • ex: 一个字符串形成一个涉及操作数和运算符的表达式
  • local_dict:一个字典,用于替换当前帧中的本地操作数。
  • global_dict:一个字典,用于替换当前帧中的全局操作数。
  • out: 一个现有的数组,结果将被存储在这里。需要注意确保这个数组的大小与结果数组的大小一致。
  • order: 控制操作数的迭代顺序。
  • casting: 控制在进行复制或缓冲时可能发生的数据转换。

返回:结果数组

示例 1:

在这个例子中,我只使用了evaluate函数的ex参数来执行a和b之间的加法。

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
b = np.array([[19, 17], [13, 19]])
  
print(ne.evaluate('a+b'))

输出:

[[25. 23.]
[13. 26.]]

示例 2:

在这个例子中,我用local_dict参数和ex一起,从局部范围传递c和d的操作数。

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
b = np.array([[19, 17], [13, 19]])
  
print(ne.evaluate('c+d', local_dict={'c': a, 'd': b}))

输出:

[[25. 23.]
[13. 26.]]

示例 3:

在这个例子中,我用global_dict参数来传递d的操作数,而用local_dict参数来传递ex参数中c的操作数。

import numpy as np
import numexpr as ne
  
a = np.array([[6, 6], [0, 7]])
  
def calc():
    b = np.array([[19, 17], [13, 19]])
    out = np.zeros((2, 2))
    ne.evaluate('c+d', local_dict={'c': b},
                global_dict={'d': a}, out=out)
    print(out)
  
calc()

输出:

[[25. 23.]
[13. 26.]]

对比性能

现在,让我们把我们的学习成果用于测试。在下面的例子中,我们将使用NumPy和NumExpr进行同样的操作,并使用timeit对其进行计时。

示例 1:

我们将执行一个简单的代数表达式,涉及对两行向量的加法和乘法,每个向量的大小为1000000。为了做到这一点,我们使用了NumPy包中的加法和乘法函数,并从NumExpr中评估,以模仿它。

import numpy as np
import numexpr as ne
  
a = np.arange(1000000)
b = np.arange(1000000)
  
timeit np.add(np.multiply(2, a), np.multiply(4, b))
timeit ne.evaluate('2*a+4*b')

输出:

Numpy向量操作的并行化

输出

Numpy向量操作的并行化

示例 2:

在这个例子中,我们将使用NumPy库中的sin函数,以及使用NumExpr的对应函数对一个1000000大小的行向量进行评估。

import numpy as np
import numexpr as ne
  
a = np.arange(1000000)
  
timeit np.sin(a)
timeit ne.evaluate('sin(a)')

输出:

Numpy向量操作的并行化

输出

Numpy向量操作的并行化

示例 3:

在这个例子中,我们将使用NumPy库中的cos函数及其对应的NumExpr的evaluate函数来处理一个(10000, 10)大小的矩阵。

import numpy as np
import numexpr as ne
  
a = np.random.randint(0, 1000, size=(10000, 10))
  
timeit np.cos(a)
timeit ne.evaluate('cos(a)')

输出:

Numpy向量操作的并行化

输出

Numpy向量操作的并行化

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程