【问题标题】:Python random not working likePython随机无法正常工作
【发布时间】:2014-07-16 10:09:53
【问题描述】:

尝试的问题:两个骰子中的一个比第三个骰子的值更高的概率。

问题:由于某种原因,当我使用 python 中的 random 模块(特别是示例方法)时,我最终得到了与使用 numpy 时不同(且不正确)的结果.我已将结果包含在底部。重复执行代码会产生类似的结果。任何想法,为什么random.sample 方法和numpy.random.random_integers 具有不同的结果,即使它们具有相同的功能?

import numpy as np                                                              
import random                                                                   


random_list = []                                                                
numpy_list = []                                                                 
n= 500                                                                          
np_wins = 0                                                                     
rand_wins = 0                                                                   
for i in range(n):                                                              
    rolls = random.sample(range(1,7), 3)                                        
    rand_wins += any(rolls[0] < roll for roll in rolls)                         

    rolls = np.random.random_integers(1, 6, 3)                                  
    np_wins += any(rolls[0] < roll for roll in rolls)                           


print "numpy : {}".format(np_wins/(n * 1.0))                                    
print "random : {}".format(rand_wins/(n * 1.0))           

结果

Press ENTER or type command to continue numpy : 0.586 random : 0.688

【问题讨论】:

    标签: python numpy random


    【解决方案1】:

    观察到差异的原因是random.sample 样本没有替换(参见here),而numpy.random.random_integers 样本有替换。

    【讨论】:

      【解决方案2】:

      random.sample() 防止双重值。这就像绘制数字而不替换它们,所以像[ 1, 1, 1 ] 这样的结果永远不会出现。

      另一方面,如果您模拟三个掷骰子,np.random.random_integers() 是您真正想要的。

      您可以将random.sample() 替换为[ random.randint(1, 6) for _ in range(3) ] 之类的东西,以达到相同的效果。

      【讨论】:

        【解决方案3】:

        这里有两个问题(一个小问题,一个重要问题):

        1. 您的样本量非常小,无法获得良好的结果。如果我只滚动 500 次,我得到的结果在 0.55 到 0.62 之间。几乎不准确。

        2. random.sample 从给定序列中选择 3 个项目不放回。因此,您不是在掷三个骰子,而是从 [1, 6] 范围内选择三个不同的数字。

          事实上,如果我这样做,概率是 67 %,而对于你所说的问题,它更接近 58 %,正如你所观察到的。

        我使用的PowerShell测试代码:

        原始问题陈述:

        (1..500 | %{
           $r = 0..2 | %{ Get-Random -min 1 -max 7 }
           !!($r|?{$r[0] -lt $_})
        } | measure -ave).Average
        

        你有缺陷的方法:

        (1..500 | %{
           $r = 1..6 | Get-Random 3
           !!($r|?{$r[0] -lt $_})
        } | measure -ave).Average
        

        这些产生的结果差异与您观察到的相同。

        【讨论】:

        • 对问题的良好解释,以及用于识别相对较小的样本部分的 +1。值得注意的是,numpy.random.random_integers() 会产生正确的结果,解决问题 #2,同时将样本增加到 n=100000 会缓解问题 #1。
        猜你喜欢
        • 1970-01-01
        • 2018-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        相关资源
        最近更新 更多