抛一枚硬币 100 次并计算正面朝上的次数。重复此模拟 10**5 次
Tossing a fair coin for 100 times and count the number of heads. Repeat this simulation 10**5 times
编写一个程序,模拟抛100次公平硬币并计算正面朝上的次数。重复此模拟 10**5 次以获得人数分布。
我写了下面的代码来计算正面的数量 100 次,外循环应该重复我的函数 100K 次以获得正面的分布:
import random
def coinToss():
return random.randint(0, 1)
recordList = []
for j in range(10**5):
for i in range(100):
flip = coinToss()
if (flip == 0):
recordList.append(0)
print(str(recordList.count(0)))
但是每次我 运行 我的程序,我得到的不是 100K 正面概率的列表,而是没有#s 更高,谁能告诉我我做错了什么?
42
89
136
....
392
442
491
由于原题要求的是正面朝上的分布,因此您需要跟踪两个列表:一个是每次 100 次试掷的正面朝上数,另一个是当前 100-折腾试验。
import random
def coinToss():
return random.randint(0, 1)
experiments = [] # Number of heads per 100-toss experiment
for j in range(10**5):
cnt = [] # Number of heads in current 100-toss experiment
for i in range(100):
flip = coinToss()
if (flip == 0):
cnt.append(0)
experiments.append(cnt.count(0))
print(str(cnt.count(0)))
但是,我强烈建议在类似 numpy
的情况下执行此操作,这将大大提高性能。你可以用 numpy
:
一行来做到这一点
import numpy as np
experiments = np.random.binomial(n=100, p=0.5, size=10**5)
然后您可以使用您想要的任何工具(例如 numpy
、matplotlib
)analyze/plot 人数分布。
这是一个带有 numpy 的版本,可以让您更优雅地生成随机数,因为您还可以指定大小属性。
import numpy as np
n_sim = 10
n_flip = 100
sims = np.empty(n_sim)
for j in xrange(n_sim):
flips = np.random.randint(0, 2, n_flip)
sims[j] = np.sum(flips)
您可能会注意到您的正面数量每次都增加了 ~50 个。这是因为您没有在每次循环时将记录计数器重置为 []。如果您在 print 语句之后直接添加 "recordList = []" 并使用相同的缩进,它基本上会修复您的代码。
执行此操作的另一种巧妙方法是将 100 次硬币翻转实验包装在一个函数中,然后调用该函数 10**5 次。您还可以使用列表理解来使一切变得简洁明了:
import random
def hundred_flips():
result = sum([random.randint(0, 1) for i in range(100)])
return result
all_results = [hundred_flips() for i in range(10**5)]
您可以用所有抛硬币模拟一个矩阵,然后在该矩阵上进行计算。
from numpy import mean, std
from numpy.random import rand
N_flip = int(1e5)
N_trials = int(1e2)
coin_flips = rand(N_flip, N_trials) > 0.5
p = mean(coin_flips, axis=0) # Vector of length N_trials with estimated probabilites
print('Mean: %3.2f%%, Std: %3.2f%%' % (mean(p)*100, std(p)*100))
编写一个程序,模拟抛100次公平硬币并计算正面朝上的次数。重复此模拟 10**5 次以获得人数分布。
我写了下面的代码来计算正面的数量 100 次,外循环应该重复我的函数 100K 次以获得正面的分布:
import random
def coinToss():
return random.randint(0, 1)
recordList = []
for j in range(10**5):
for i in range(100):
flip = coinToss()
if (flip == 0):
recordList.append(0)
print(str(recordList.count(0)))
但是每次我 运行 我的程序,我得到的不是 100K 正面概率的列表,而是没有#s 更高,谁能告诉我我做错了什么?
42
89
136
....
392
442
491
由于原题要求的是正面朝上的分布,因此您需要跟踪两个列表:一个是每次 100 次试掷的正面朝上数,另一个是当前 100-折腾试验。
import random
def coinToss():
return random.randint(0, 1)
experiments = [] # Number of heads per 100-toss experiment
for j in range(10**5):
cnt = [] # Number of heads in current 100-toss experiment
for i in range(100):
flip = coinToss()
if (flip == 0):
cnt.append(0)
experiments.append(cnt.count(0))
print(str(cnt.count(0)))
但是,我强烈建议在类似 numpy
的情况下执行此操作,这将大大提高性能。你可以用 numpy
:
import numpy as np
experiments = np.random.binomial(n=100, p=0.5, size=10**5)
然后您可以使用您想要的任何工具(例如 numpy
、matplotlib
)analyze/plot 人数分布。
这是一个带有 numpy 的版本,可以让您更优雅地生成随机数,因为您还可以指定大小属性。
import numpy as np
n_sim = 10
n_flip = 100
sims = np.empty(n_sim)
for j in xrange(n_sim):
flips = np.random.randint(0, 2, n_flip)
sims[j] = np.sum(flips)
您可能会注意到您的正面数量每次都增加了 ~50 个。这是因为您没有在每次循环时将记录计数器重置为 []。如果您在 print 语句之后直接添加 "recordList = []" 并使用相同的缩进,它基本上会修复您的代码。
执行此操作的另一种巧妙方法是将 100 次硬币翻转实验包装在一个函数中,然后调用该函数 10**5 次。您还可以使用列表理解来使一切变得简洁明了:
import random
def hundred_flips():
result = sum([random.randint(0, 1) for i in range(100)])
return result
all_results = [hundred_flips() for i in range(10**5)]
您可以用所有抛硬币模拟一个矩阵,然后在该矩阵上进行计算。
from numpy import mean, std
from numpy.random import rand
N_flip = int(1e5)
N_trials = int(1e2)
coin_flips = rand(N_flip, N_trials) > 0.5
p = mean(coin_flips, axis=0) # Vector of length N_trials with estimated probabilites
print('Mean: %3.2f%%, Std: %3.2f%%' % (mean(p)*100, std(p)*100))