numpy库和for循环效率比较:(原因分析在最后的链接中)
本文是在Windows命令行中使用 jupyter nbconvert --to markdown “numpy.dot_vs_for_loop.ipynb” 转换的,原文地址:原文
import numpy as np
import time
创建两个百万维的数组
a = np.random.rand(1000000)
b = np.random.rand(1000000)
分别用np.dot和for循环对两个数组进行点乘
begin = time.time()
c = np.dot(a,b)
end = time.time()
print(c)
print("使用np.dot方法(向量化)用的时间:{} ms.".format(1000*(end-begin)))
c = 0
begin = time.time()
for i in range (1000000):
c += a[i]*b[i]
end = time.time()
print(c)
print("使用for循环用的时间:{} ms.".format(1000*(end-begin)))
249715.57341423497
使用np.dot方法(向量化)用的时间:1.9905567169189453 ms.
249715.57341423733
使用for循环用的时间:1073.1749534606934 ms.
对向量的每个元素进行指数运算
import math
a = np.random.random((1000000,1))
begin = time.time()
b = np.exp(a)
end = time.time()
print("使用np.exp方法(向量化)用的时间:{} ms.".format(1000*(end-begin)))
c = np.zeros((1000000,1))
begin = time.time()
for i in range(1000000):
c[i] = math.exp(a[i])
end = time.time()
print("使用for循环用的时间:{} ms.".format(1000*(end-begin)))
print(np.allclose(b,c))
使用np.exp方法(向量化)用的时间:6.981849670410156 ms.
使用for循环用的时间:1491.574764251709 ms.
True
对于numpy的矩阵v,还可以使用np.log(v),np.abs(v),np.maximum(), v**2, 1/v等操作
可以自定义函数作用于vector的每个元素
import numpy as np
def mf(x,y):
return x ** 3 + 2 * x - 1 if x > y else x * 3 + 8
f = np.vectorize(mf)
A = np.random.randint(-10,10,size=(6,6))
result_array = f(A,2)
A
array([[ -7, -6, -5, -2, 0, -5],
[ 5, 5, 0, 7, -2, -9],
[ -6, 3, -5, -6, -2, -8],
[-10, -5, 3, -6, 7, 5],
[ -9, -7, 5, 3, -2, 2],
[ -2, -2, 6, -6, 2, 9]])
result_array
array([[-13, -10, -7, 2, 8, -7],
[134, 134, 8, 356, 2, -19],
[-10, 32, -7, -10, 2, -16],
[-22, -7, 32, -10, 356, 134],
[-19, -13, 134, 32, 2, 14],
[ 2, 2, 227, -10, 14, 746]])
原因: numpy是建立在对向量数学运算进行了很多艰苦优化的低级库之上的,它和for循环的内部细节不同,优化很复杂,参考一个例子:Fast inverse square root,更多原因参考:Is using NumPy faster than using for-loops to handle lists, and why?