【问题标题】:What is vectorization? [closed]什么是矢量化? [关闭]
【发布时间】:2018-05-25 02:59:22
【问题描述】:

在 Python 中向量化 for 循环是什么意思?是否有另一种编写嵌套 for 循环的方法?

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

【问题讨论】:

    标签: python python-3.x numpy vectorization


    【解决方案1】:

    这是来自 Wes McKinney 的 definition

    数组很重要,因为它们使您能够表达批处理 无需编写任何 for 循环即可对数据进行操作。这通常是 称为矢量化。相等大小之间的任何算术运算 arrays 按元素应用操作。

    矢量化版本:

    >>> 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 ns; Python 版本需要 3.52 µs (3520 ns)。这种“小”时间的巨大差异称为微性能,当您处理较大的数据或重复操作数千或数百万次时,它变得很重要。

    【讨论】:

      【解决方案2】:

      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 倍。

      【讨论】:

      • 对于任何想知道为什么矢量化操作(在硬件级别上)如此之快的人可以找到答案here
      • 仅说明 numpy 将 for 循环推送到 C(并没有解释向量化是如何在那里完成的(以及机器字节码执行的较低级别))是不够的。
      猜你喜欢
      • 2010-11-28
      • 2010-12-03
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 2021-03-01
      • 2010-09-29
      • 1970-01-01
      相关资源
      最近更新 更多