速度比较。 numpy vs python标准

时间:2018-10-02 07:08:56

标签: python numpy random

我做了一些实验,发现许多情况下python的标准randommath库比numpy对应库快。

我认为,对于小规模的操作,python的标准库有大约10倍的速度增长,而对于大规模(矢量)操作,numpy则有更快的趋势。我的猜测是numpy有一些开销,在小情况下会占主导地位。

我的问题是:我的直觉正确吗?在小型(通常是标量)操作中,通常建议使用标准库而不是numpy吗?

示例如下。

import math
import random
import numpy as np

日志和指数

%timeit math.log(10)
# 158 ns ± 6.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit np.log(10)
# 1.64 µs ± 93.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit math.exp(3)
# 146 ns ± 8.57 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit np.exp(3)
# 1.72 µs ± 78.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

生成正态分布

%timeit random.gauss(0, 1)
# 809 ns ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.random.normal()
# 2.57 µs ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

选择随机元素

%timeit random.choices([1,2,3], k=1)
# 1.56 µs ± 55.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.random.choice([1,2,3], size=1)
# 23.1 µs ± 1.04 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

与numpy数组相同

arr = np.array([1,2,3])

%timeit random.choices(arr, k=1)
# 1.72 µs ± 33.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.random.choice(arr, size=1)
# 18.4 µs ± 502 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

大阵列

arr = np.arange(10000)

%timeit random.choices(arr, k=1000)
# 401 µs ± 6.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit np.random.choice(arr, size=1000)
# 41.7 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

2 个答案:

答案 0 :(得分:5)

numpy实际上只是对大数据块的性能改进。如果将数组ndarray插入c编译的numpy函数中,确保数组正确对齐的开销通常会浪费很多时间,如果数组不是相对较大的话。这就是为什么如此多的numpy问题基本上是“我如何使用此循环代码并使之快速运行”的原因,以及为什么在几乎所有其他标签都将您扔向{{3 }},直到他们超越标题。

所以,是的,您的观察是可概括的。向量化是numpy的重点。未向量化的numpy代码总是比裸python代码要慢,并且可以说与用手提钻破解单个胡桃木一样“错误”。找到合适的工具,或者得到更多的螺母。

答案 1 :(得分:4)

NumPy主要用于数组的性能。这依赖于使用连续的内存块和更有效的低级迭代。在标量上应用NumPy数学函数或计算随机数不是矢量化操作。这说明了您所看到的行为。

另请参阅What are the advantages of NumPy over regular Python lists?

  

通常建议使用标准库而不是   比NumPy小(通常是标量)运算?

很少有程序的瓶颈是由标量运算引起的。实际上,差异可以忽略不计。所以这两种方法都很好。如果您已经在使用NumPy,则继续在标量上使用NumPy操作没有任何危害。

值得一提特殊情况下计算随机数。如您所料,通过random和NumPy选择的随机数可能不同:

assert random.gauss(0, 1) == np.random.normal()  # AssertionError
assert random.choices(arr, k=1)[0] == np.random.choice(arr, size=1)[0]  # AssertionError

您在NumPy中具有其他功能,可以使随机数“可预测”。例如,重复运行以下脚本只会产生相同的结果:

np.random.seed(0)
np.random.normal()

np.random.choice也是如此。因此,方法的不同之处在于随机数的导出方式和可用功能。为了测试或其他目的,您可能希望能够产生一致的“随机”数字。