【问题标题】:sample n random permutations of a list in python [duplicate]在python中对列表的n个随机排列进行采样[重复]
【发布时间】:2021-09-15 07:28:30
【问题描述】:

我有一个值列表,例如:

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

我需要可重复地返回此列表的 n 次随机洗牌。

理想情况下,我需要一个带有种子的函数,例如 f(lst, samples = 2, seed = 1234) -> 返回两个随机列表lst 如:

[5, 7, 1, 6, 2, 8, 0, 4, 3, 9]
[8, 7, 3, 0, 1, 4, 5, 9, 6, 2]

重复执行此函数(使用相同的种子)将返回相同的两个列表。

【问题讨论】:

  • 你试过什么?
  • @Ade_1 我尝试了一些 np、sklearn 工具和 itertools.permutations。问题是我需要 n 次洗牌。 np 和 sklearn 只返回一次随机播放。 itertools 返回所有排列,如果输入列表很长,我会用完内存。
  • 你试过使用随机库吗?
  • @tevemadar 否,因为它不会生成 n 次随机播放。一次可重复的 shuffle 不是问题。
  • @user2743931 然后产生一个n次?

标签: python random shuffle


【解决方案1】:

这在没有numpy 的情况下有效:

import sys
import random

some_seed = 123  # change this to get different shuffles

def n_shuffles(lst, n):
    r = random.Random(some_seed)
    for _ in range(n):
        _l = lst[:]
        r.shuffle(_l)
        yield _l


l = list(range(10))
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]

【讨论】:

  • 通过在每次洗牌前播种不同的种子,其想法是减少重复相同洗牌的可能性。但除了最微不足道的输入之外,其他所有输入的差异可能都可以忽略不计。
  • 没错,这完全没有必要。删除了双播。
  • 不,那是因为你那里的random.random() 行消耗了一个随机数并改变了Random 对象的状态。
  • 好的,现在使用一个独立的Random 对象来保持它的生成器。
【解决方案2】:

你可以使用np.copy

import numpy as np

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


def shuffle_list(arr:list,samples:int,seed:int):
    np.random.seed(seed)
    res = []
    for i in range(samples):
        arr_copy=np.copy(arr)
        np.random.shuffle(arr_copy)
        res.append(arr_copy)
    return res


#test
print(shuffle_list(lst,2,1234))

输出:

[array([7, 2, 9, 1, 0, 8, 4, 5, 6, 3]), array([7, 3, 5, 1, 4, 8, 0, 2, 6, 9])]

【讨论】:

  • 这看起来不错,谢谢!我不知道种子可以用于在 for 循环中生成随机但可重现的随机播放
  • @user2743931 因为您甚至没有查看副本。
  • @joostblack,认识random.sample()
【解决方案3】:

好的,这不是一个精确重复的,但提议的主题已经几乎表明重新设置seed()是关键:

import random

def shuffles(l,n):
  random.seed(4) # just the same one as in the referred topic
  return [random.sample(l,k=len(l)) for i in range(n)]

print(shuffles([1,2,3,4],3))
print("again:")
print(shuffles([1,2,3,4],3))

会生成

[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]                            
again:                                                                
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]

【讨论】:

    【解决方案4】:

    您可以使用[:]listnumpy.random.shuffle 创建副本 随机播放list,如下所示:

    import numpy as np
    
    def shuffle_lst(lst, samples = 2, seed = 1234):
        np.random.seed(seed)
        L_lst = [lst[:] for i in range(samples)]
        [np.random.shuffle(L_lst[i]) for i in range(samples)]
        return L_lst
    
    lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(f'Iter 1: {shuffle_lst(lst)}')
    print(f'Iter 2: {shuffle_lst(lst)}')
    print(f'Iter 2: {shuffle_lst(lst)}')
    

    输出:

    Iter 1: [[7, 2, 9, 1, 0, 8, 4, 5, 6, 3], [7, 3, 5, 1, 4, 8, 0, 2, 6, 9]]
    Iter 2: [[7, 2, 9, 1, 0, 8, 4, 5, 6, 3], [7, 3, 5, 1, 4, 8, 0, 2, 6, 9]]
    Iter 2: [[7, 2, 9, 1, 0, 8, 4, 5, 6, 3], [7, 3, 5, 1, 4, 8, 0, 2, 6, 9]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 2019-05-31
      • 2021-10-05
      • 2020-07-10
      • 1970-01-01
      • 2015-11-14
      相关资源
      最近更新 更多