Numpy
作者:PureFFFmennory
对象类型:ndarry
上一节:伪随机数与随机变量分布的生成PureFFFmennory:《Python for Data Analysis 2nd》学习笔记 4.6 伪随机数与随机变量生成zhuanlan.zhihu.com
4.7 随机数示例:随机步进
随机步进的模拟提供了利用数组操作的说明性应用。让我们首先考虑一个简单的随机步进,从0开始,步长为1和-1且它们的概率相等。
下面是使用Python内置的随机模块实现,他是具有1000个步骤的单个随机遍历的纯Python方法:
>> import random
>> position = 0
>> walk = [position]
>> steps = 1000
>> for i in range(steps):
>> step = 1 if random.randint(0, 1) else -1
>> position += step
>> walk.append(position)
>>
下图是一个随机步进的前100个值的示例图:
>> plt.plot(walk[:100])
你可能会观察到,步行只是简单的随机数步进的累计总和,它也可以作为数组表达式来计算。因此,我使用np.random模块来一次性绘制1000掷硬币的结果,将这些触发器设置为1和-1,并计算累计总和:
>> nsteps = 1000
>> draws = np.random.randint(0, 2, size=nsteps)
>> steps = np.where(draws > 0, 1, -1)
>> walk = steps.cumsum()
从这里,我们可以开始提取统计数据,如步进轨迹的最小值与最大值。
>> walk.min()
# 打印输出:-3
>> walk.max()
# 打印输出:31
更复杂的统计是第一个交叉时间,即随机步进达到特定值的步数。在这里,我们可能想知道随机步进需要多长时间才能从原点0到任一方向至少到达10的距离。np.abs(walk) >= 10为我们提供了一个布尔数组,指示步进点已达到或超过10的位置,但我们希望得到第一个10或-10。事实证明,我们可以使用argmax来计算,argmax返回布尔数组中最大值的第一个索引:
>> (np.abs(walk) >= 10).argmax()
# 打印输出:37
请注意,在此使用argmax并不是总是有效的,因为它总是对数组进行完全扫描。在这个特殊情况下,一旦遇到True,我们便知道它是最大值。
一次性模拟多个随机步进行走
如果你的目标是模拟许多随机步进(例如5000次随机步进),则可以将刚刚的代码做细微的修改来生成所有随机步进。如果参数传递一个2-tuple,numpy.random函数将生成一个二维的数组,我们可以计算行的累计总和使得在一次操作中计算所有5000个随机步进:
>> nwalks = 5000
>> nsteps = 1000
>> draws = np.random.randit(0, 2, size=(nwalks, nsteps)) # 0 或 1
>> steps = np.where(draws > 0, 1, -1)
>> walks = steps.cumsum(1)
现在,我们可以在所有的步进中计算获取的最大值与最小值:
>> walks.max()
>> walks.min()
在这些步进中,让我们计算到-30或30的最小交叉时间。这有些棘手,因为并非所有5000个步进都达到了30.我们可以使用any方法来检查这个情况:
>> hits30 = (np.abs(walks) >= 30).any(1)
# 打印输出布尔数组
>> hits30.sum() # 到达30或-30的数
# 输出求和
我们可以使用这个布尔数组来选择实际跨越绝对值为30级别的步进行,并使用argmax(参数为轴1)以获得交叉时间:
>> crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)
>> crossing_times.mean()
你可以随意的尝试其他分布的步进而不是像掷硬币的等概率分布。你只需要使用不同的随机数生成函数如正态分布,以生成一些均值和标准差为正态分布的步进:
>> steps = np.random.normal(loc=0, scale=0.25, size=(nwalks, nsteps))
下一节:4.8 总结PureFFFmennory:《Python for Data Analysis 2nd》学习笔记 4.8 总结zhuanlan.zhihu.com