【问题标题】:Random selection from list with replacement从列表中随机选择替换
【发布时间】:2015-04-10 17:42:03
【问题描述】:

我有一个列表列表,如下所示:

a = [[1,2],[2,3]]

我想从a 创建一个给定大小的随机列表替换numpy.random.choice() 方法只接受一维数组。我可以编写自己的函数来做到这一点,但是已经有优化的方法了吗?

预期输出

[[1,2],[1,2],[2,3],[2,3]] 
// the size (4 here) has to be a parameter passed to the function

【问题讨论】:

  • 你能举例说明你的预期输出吗?
  • 您想要子列表还是整数列表?如果是后者,列表是否保证包含整数列表,或者它们可能嵌套得比两层更深或更浅?
  • @BrendanLong:我刚刚添加了预期的输出
  • @BlacklightShining:我想要一个子列表

标签: python numpy random


【解决方案1】:

您可以简单地反复拨打the standard library's random.choice()。不需要numpy

>>> list_of_lists = [[1, 2], [2, 3]]
>>> sample_size = 4
>>> [random.choice(list_of_lists) for _ in range(sample_size)]
[[1, 2], [2, 3], [1, 2], [1, 2]]

这是random.sample() 的替代方案,无需替换即可工作,让您选择大于原始总体规模的“样本”。

【讨论】:

    【解决方案2】:

    使用 numpy:

    size = 4
    a = np.array([[1,2],[2,3]])
    b = np.random.randint(len(a), size = size)
    a[b,:]
    
    Out[93]:
    array([[2, 3],
           [2, 3],
           [2, 3],
           [1, 2]])
    

    【讨论】:

      【解决方案3】:

      从 Python 3.6 开始,您可以直接使用random.choices

      random.choices(list_of_lists, k=sample_size)
      ## [[1, 2], [3, 4], [3, 4], [1, 2]]
      

      一个粗略的基准表明,在不同的样本量上,这似乎比列表理解方法更有效。

      >>> list_of_lists = [[1, 2], [3, 4]]
      >>> sample_size = 4
      
      >>> %timeit [random.choice(list_of_lists) for _ in range(sample_size)]
      4.49 µs ± 20.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      >>> %timeit random.choices(list_of_lists, k=sample_size)
      1.99 µs ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      >>> list_of_lists *= 100
      >>> sample_size *= 1000
      
      >>> %timeit [random.choice(list_of_lists) for _ in range(sample_size)]
      3.54 ms ± 28.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      
      >>> %timeit random.choices(list_of_lists, k=sample_size)
      927 µs ± 1.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

      【讨论】:

        【解决方案4】:

        more_itertools 库实现了more_itertools.random_combination_with_replacement

        import more_itertools as mit
        
        list_of_lists = [[1, 2], [2, 3]]
        sample_size = 4
        list(mit.random_combination_with_replacement(list_of_lists, sample_size))
        # [[1, 2], [1, 2], [2, 3], [2, 3]]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-19
          • 2012-04-30
          • 2021-12-15
          相关资源
          最近更新 更多