编程语言
首页 > 编程语言> > 基于蒙特卡罗的Pi计算的Python高效矢量化

基于蒙特卡罗的Pi计算的Python高效矢量化

作者:互联网

为了近似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

注意随机数生成依赖于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

现在考虑非矢量化方法,

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

非矢量化形式的平均速度比矢量化版本快4倍,例如考虑n = 5000000和OS命令行如下(Python 2.7,Quadcore,8GB RAM,RedHat Linux),

time python pi.py
time python np_pi.py

因此,要问如何改进矢量化方法以提高其性能.

解决方法:

你正在调用python内置和,而不是numpy的向量化方法总和:

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)])

时间结果现在差异很大:

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

我猜测在numpy数组上调用内置和会通过遍历数组而不是使用向量化例程来导致开销.

标签:pi,python,numpy,vectorization,montecarlo
来源: https://codeday.me/bug/20190830/1766039.html