elm*_*elm 3 python pi numpy vectorization montecarlo
要估算Pi的值,请考虑采用一种随机方法,该方法将随机值填充到数组中并测试单位圆的包含性,
import random as rd
import numpy as np
def r(_): return rd.random()
def np_pi(n):
v_r = np.vectorize(r)
x = v_r(np.zeros(n))
y = v_r(np.zeros(n))
return sum (x*x + y*y <= 1) * 4. / n
Run Code Online (Sandbox Code Playgroud)
注意,随机数的生成依赖于Python标准库;考虑通过numpy随机生成,
def np_pi(n):
x = np.random.random(n)
y = np.random.random(n)
return sum (x*x + y*y <= 1) * 4. / n
Run Code Online (Sandbox Code Playgroud)
现在考虑非矢量化方法,
import random as rd
def dart_board():
x,y = rd.random(), rd.random()
return (x*x + y*y <= 1)
def pi(n):
s = sum([dart_board() for _ in range(n)])
return s * 4. / n
Run Code Online (Sandbox Code Playgroud)
非矢量化格式的平均速度比矢量化格式要快4倍,例如考虑以下n = 5000000操作系统命令行(Python 2.7,Quadcore,8GB RAM,RedHat Linux),
time python pi.py
time python np_pi.py
Run Code Online (Sandbox Code Playgroud)
因此要问如何改进矢量化方法以提高其性能。
您正在调用python Builtin sum而不是numpy的vectorized方法sum:
import numpy as np
import random as rd
def np_pi(n):
x = np.random.random(n)
y = np.random.random(n)
return (x*x + y*y <= 1).sum()
def dart_board():
x,y = rd.random(), rd.random()
return (x*x + y*y <= 1)
def pi(n):
s = sum([dart_board() for _ in range(n)])
Run Code Online (Sandbox Code Playgroud)
现在计时结果有很大不同:
In [12]: %timeit np_pi(10000)
1000 loops, best of 3: 250 us per loop
In [13]: %timeit pi(10000)
100 loops, best of 3: 3.54 ms per loop
Run Code Online (Sandbox Code Playgroud)
我猜想sum在numpy-array上调用内建函数会通过遍历数组而不是使用矢量化例程而导致开销。
| 归档时间: |
|
| 查看次数: |
1482 次 |
| 最近记录: |