什么是向量化?

29

什么是在Python中对for循环进行向量化?是否还有其他方式来编写嵌套的for循环?

我是Python新手,在我的研究中,我经常遇到NumPy库。

2个回答

37

Python for 循环本身比其C语言对应部分慢。

这就是为什么 numpynumpy 数组上提供向量化操作。它将你通常在 Python 中执行的 for 循环下推到 C 级别,从而实现更快的速度。numpy 提供了向量化(“C级别的for循环”)替代方案,以替代必须以元素方式(“Python级别for循环)执行的任务。

import numpy as np
from timeit import Timer

li = list(range(500000))
nump_arr = np.array(li)

def python_for():
    return [num + 1 for num in li]

def numpy_add():
    return nump_arr + 1

print(min(Timer(python_for).repeat(10, 10)))
print(min(Timer(numpy_add).repeat(10, 10)))

#  0.725692612368003
#  0.010465986942008954

numpy 向量化加法快了70倍。


5
对于任何想知道为什么向量化操作在硬件层面上如此快速的人,可以在这里找到答案:https://dev59.com/ClsW5IYBdhLWcg3wVWHj。 - Philipp
1
声称NumPy将循环推到C语言(而不解释如何在那里进行矢量化(以及更低级别的机器字节码执行))是不够的。 - Sergey Bushmanov

20

以下是Wes McKinney给出的定义:

数组很重要,因为它们使您能够在不编写任何for循环的情况下对数据进行批处理操作。这通常被称为向量化。相同大小的数组之间的任何算术运算都会按元素逐个应用该运算。

向量化版本:

>>> import numpy as np
>>> arr = np.array([[1., 2., 3.], [4., 5., 6.]])
>>> arr * arr
array([[  1.,   4.,   9.],
       [ 16.,  25.,  36.]])

对于嵌套的本地Python列表,循环也是如此:

>>> arr = arr.tolist()
>>> res = [[0., 0., 0.], [0., 0., 0.]]
>>> for idx1, row in enumerate(arr):
        for idx2, val2 in enumerate(row):
            res[idx1][idx2] = val2 * val2
>>> res
[[1.0, 4.0, 9.0], [16.0, 25.0, 36.0]]

这两个操作怎么比较呢?NumPy 版本需要 436 纳秒; Python 版本需要 3.52 微秒 (3520 纳秒)。这种微小时间差异被称为微效能,当您处理大量数据或重复执行操作数千万次时,它变得非常重要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接