计算蒙特卡罗模拟中的样本均值

时间:2014-01-18 12:16:27

标签: python performance mean montecarlo

我对n个样本进行了蒙特卡罗模拟。对于每个样本i,我需要计算值Xi,我将得到的结果是:

  

X = [X1,X2,...,Xn]

(这里Xi可以是矩阵或数字)。

现在我想计算我称之为Xmean的这些样本的平均值。所以我需要获得这样的东西:

  

Xmean = [X1,(X1 + X2)/ 2,(X1 + X2 + X3)/ 3 ......,(X1 + X2 + ... + Xn)/ n]

在Python中,我编写了一个代码:

for i in range(N):
    for j in range(i+1):
         Xmean(i) = Xmean(i) + X(j)
    Xmean(i) = Xmean(i) / (i+1)

它运行良好但速度太慢,我想知道我是否可以加快这段代码的速度?如果你们可以向我推荐一些有趣的Python库来帮助进行蒙特卡罗模拟。

谢谢,

3 个答案:

答案 0 :(得分:1)

import timeit, numpy

setup = '''
from __main__ import mc0, mc1, mc2
import random, numpy

random.seed(0)
n = 10**3
data = [random.randint(0, 2**32-1) for _ in range(n)]
np_data = numpy.array([float(x) for x in data])
'''

# your implementation
def mc0(data):
    xmean = []
    for i in range(len(data)):
        xmean.append(0)
        for j in range(i+1):
            xmean[i] += data[j]
        xmean[i] = xmean[i] / (i+1)
    return xmean

# my implementation
def mc1(data):
    xmean = []
    for i, x in enumerate(data):
        if i == 0:
            new = x
        else:
            new = x/(i+1) + xmean[i-1] * (i/(i+1))
        xmean.append(new)
    return xmean

# Donbeo's numpy implementation
def mc2(data):
    xmean = numpy.cumsum(data) / numpy.array(range(1, len(data)+1))
    return xmean


number = 100
things = [('mc0', 'mc0(data)'),
          ('mc1', 'mc1(data)'),
          ('mc2', 'mc2(np_data)')]
for note, call in things:
    print('{:20} {}'.format(note,
                            timeit.timeit(call, setup=setup, number=number)))

结果:

mc0                  26.023956370918587
mc1                  0.1423197092108488
mc2                  0.13584513496654083

当你已经在x(1)..x(i)中提供了这些信息时,在每次循环迭代时重新计算xmean的总和是没有意义的。 Donbeo的numpy版本比我的纯Python版本略快,两者的速度都比原始版本快了近200倍(无论如何这些数据)。

答案 1 :(得分:0)

只需减少计算量,

Xmean(0) = X(0)
for i in range(N-1):
    Xmean(i+1) = (Xmean(i)*(i+1) + X(i+1))/(i+2)

答案 2 :(得分:0)

如果你使用numpy它应该很容易。

import numpy as np

X = [1,5,3,8,6,9]
Xmean = np.cumsum(X)
Xmean = Xmean/np.array(range(1,len(X)+1)