我对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库来帮助进行蒙特卡罗模拟。
谢谢,
答案 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)