在带有列表的Python 3中random.shuffle非常慢

时间:2018-11-19 16:15:04

标签: python-3.x list random shuffle

我正在使用python-3.x,并且尝试生成索引号列表并对其进行混洗以便以后使用它们从样本中选择随机值,其中该样本将具有两个变量样本大小和维数,但是在这里,我如何生成索引列表,并对其进行随机排序:

dimension = 5
sample_size = 100

generate_indexes = itertools.combinations(range(sample_size),dimension)
all_indexes = list(generate_indexes)

# here I do the shuffle
random.shuffle(all_indexes)

当我增加尺寸编号时出现的问题是,即使尺寸编号为5,也需要很长时间才能得出结果。

有什么方法可以使其快速?

因为我有一个包含值的多维样本,所以我想根据all_indexes选择一个随机数的值形式进行采样...

1 个答案:

答案 0 :(得分:0)

正如评论中指出的那样,您正在生成一个很大的列表,然后将其改组。这不会很快,但是取决于您的实际需求,可能会有更快的方式来获取您想要的东西。

我在计算机上运行您的代码,发现生成所有组合的列表大约需要8秒,改组大约需要75秒。如果您需要增加尺寸,那么这段时间将大大增加,更不用说内存需求了存储非常大的阵列的重要性可能开始变得重要起来。

如果您不需要所有随机索引,最好每次使用

进行采样
random.sample(range(sample_size), dimension)

这将返回从dimension0的不同sample_size个元素的随机集合。使用dimensionsample_size的值运行大约需要0.0001秒。如果您不需要太多的随机值,那么每次生成一个新的随机数的速度就会更快(并且内存效率更高)。

我可以看到两个问题。首先,不能保证每个新样本都不会重复以前的样本,但是可以通过将其随手存储并检查它们是否已经使用来轻松解决。

new_sample = random.sample(range(sample_size), dimension)
if new_sample not in random_indexes:
    random_indexes.append(new_sample)
else:
    # Handle this however you need. 

这确实增加了运行时间,但是如果您不需要太多样本,则再次会更快。

另一个区别是您使用的方法生成的元素的元组始终排序,因此(1,2,3,4,5)将是all_indexes的元素,但是(5,4, 3,2,1)不会。使用random.sample可以按任何顺序生成它们,因此两者都可能发生。如果这是一个问题,那么您将必须解决此问题。也许可以在将它们添加到列表之前将它们放入集合中:

new_sample = set(random.sample(range(sample_size), dimension))