【问题标题】:best way to loop through randomly generated array循环遍历随机生成的数组的最佳方法
【发布时间】:2021-12-12 07:15:14
【问题描述】:

我正在尝试解决一个问题,我生成一个三个随机数数组并循环遍历它,直到它的总和小于或等于 21。 我的问题是,是否有比以下更好/更高效的方法来做到这一点,只是为了让自己适应最佳实践。

rng = np.random.default_rng()
a = 1
while a == 1:
    rints = rng.integers(low=1, high=11, size=3)
    suma = np.sum(rints)
    if (suma <= 21):
        print(rints, suma)
        break

谢谢!

【问题讨论】:

  • @j1-lee 谢谢!!

标签: python numpy performance loops


【解决方案1】:

numpy 中,我们更喜欢使用整个数组,一次做“很多”事情,而不是迭代。

例如,与其一次只生成 3 个随机数,不如生成很多(猜 20 个):

In [88]: rng = np.random.default_rng()
In [89]: rints= rng.integers(low=1, high=11, size=(20,3))
In [90]: rints
Out[90]: 
array([[ 8,  2,  1],
       [ 5,  3,  9],
       [ 5,  3,  6],
       [10,  3,  6],
       [ 4,  9,  1],
       [ 9,  8,  2],
       [ 3,  3, 10],
       [ 1,  3,  5],
       [ 5,  6,  1],
       [ 6,  7,  9],
       [10,  4,  2],
       [ 1,  8,  1],
       [ 6,  7,  8],
       [ 3,  7,  9],
       [ 8, 10, 10],
       [ 7,  6,  8],
       [ 5,  1,  4],
       [ 4,  9, 10],
       [ 1,  8,  8],
       [ 7,  1,  9]])

然后我们可以通过 3s 相加,确定有多少是合格的:

In [91]: rints.sum(axis=1)
Out[91]: 
array([11, 17, 14, 19, 14, 19, 16,  9, 12, 22, 16, 10, 21, 19, 28, 21, 10,
       23, 17, 17])
In [92]: np.nonzero(_<=21)
Out[92]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 11, 12, 13, 15, 16, 18, 19]),)

从这个样本来看,你的while 会更快,因为早期的集合很有可能会获得资格。另一方面,如果标准大于 21,那么我们必须生成更多才能获得至少一个。

测试速度取决于随机数的问题的效率是困难的,甚至可能毫无意义。根据数量和条件,它可能会快速运行,也可能需要很长时间(例如,测试总和 >=30)。

【讨论】:

    【解决方案2】:

    使用 itertools 只是一个更短的形式

    import numpy as np
    from itertools import dropwhile
    
    rng = np.random.default_rng()
    rints = list(dropwhile(lambda x: np.sum(x)>21, rng.integers(low=1, high=11, size=3)))
    
    print(rints, np.sum(rints))
    

    【讨论】:

      【解决方案3】:

      while 循环和 if 语句可以结合使用。这样会更有效率。

      rng = np.random.default_rng()
      target_value = 21
      suma = 999
      while suma >= target_value:
          rints = rng.integers(low=1, high=11, size=3)
          suma = np.sum(rints)
      

      我还建议将其发布到code review。他们更适合这类问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-14
        • 1970-01-01
        • 2014-01-07
        • 2018-11-13
        • 1970-01-01
        • 2012-05-16
        • 2010-11-03
        • 1970-01-01
        相关资源
        最近更新 更多