这就是我已经拥有的:
import numpy as np
import matplotlib.pyplot as plt
def monteCarloPi(n):
np.random.seed() #seed the random number generator
y = np.random.rand(n)*2 - 1 #n random samples on (-1,1)
x = np.linspace(-1,1,n) #x axis to plot against
square = np.array([x,y]) #collecting axes as a single object
mask1 = ((x**2 + y**2) < 1) #filters
hits = np.sum(mask1) #calculating approximation
ratio = hits/n
pi_approx = ratio * 4
return pi_approx
这是我想要要做的事情:
x = np.arange(100,1000)
y = monteCarloPi(x)
plt.scatter(x,y)
但是,当我运行上述代码块时,出现以下错误:
---------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-52-bf4dcedaa309> in <module>()
1 x = np.arange(100,1000)
----> 2 y = monteCarloPi(x)
3 plt.scatter(x,y)
<ipython-input-51-8d5b36e22d4b> in monteCarloPi(n)
1 def monteCarloPi(n):
2 np.random.seed() #seed the random number generator
----> 3 y = np.random.rand(n)*2 - 1 #n random samples on (-1,1)
4 x = np.linspace(-1,1,n) #x axis to plot against
5
mtrand.pyx in mtrand.RandomState.rand()
mtrand.pyx in mtrand.RandomState.random_sample()
mtrand.pyx in mtrand.cont0_array()
TypeError: only integer scalar arrays can be converted to a scalar index
根据我对numpy
中广播工作原理的了解,该应该工作。我可以只使用for
循环,但是随着样本数量的增加,循环会变得非常缓慢。
半音
答案 0 :(得分:0)
这里是一个基于最大样本量的选项,然后如果start>0
(不包括错误处理)进行二次采样。
import numpy as np
import matplotlib.pyplot as plt
def monteCarloPi(n,start=0,stride=1):
np.random.seed() # seed the random number generator
y = np.random.rand(n)*2 - 1 # n random samples on (-1,1)
x = np.linspace(-1,1,n) # x axis to plot against
mask = ( x**2 + y**2 ) < 1 # masking
samples = {}
inds = arange(n)
for k in range(n-start,n+1,stride):
sub_inds = np.random.choice(inds,k,replace=False)
sub_mask = mask[sub_inds]
sub_hits = np.sum(sub_mask)
ratio = sub_hits/n
pi_approx = ratio * 4
samples[k]=pi_approx
return pi_approx
这仍然需要for循环,但是由于您是从一个大型随机样本中进行二次采样,因此可以在方法内部快速进行处理。重新创建您的原始通话(从n=100
到n=1000
[请注意,我要在n=1000
上运行):
estimates = monteCarloPi(1000,start=900)
plt.plot(estimates.keys(),estimates.values())
您当然可以传递原始的x=arange(100,1001)
,但是然后需要在方法中进行错误检查(以确保传递了数组或列表),然后n
等于到x
(n=x[-1]
)的最后一个元素,最后,循环将在x
(for k in x:
)的元素上进行。