Python itertools 创建随机子集的迭代器

use*_*412 4 python random iterator python-itertools

我有一个itertools.combinations(big_matrix,50)带有 的迭代器big_matrix.shape = (65,x),所以大约有 10^14 种组合。我想获得 10000 个这样的组合的随机子集,也作为迭代器,以节省内存。

我尝试了 itertools 食谱

def random_combination(iterable, r):
  "Random selection from itertools.combinations(iterable, r)"
  pool = tuple(iterable)
  n = len(pool)
  indices = sorted(random.sample(xrange(n), r))
  return tuple(pool[i] for i in indices)
Run Code Online (Sandbox Code Playgroud)

tuple(iterable)会创建一个包含 10^14 个值的元组,并且该函数不返回迭代器而是返回数组。

random.sample不起作用,因为它无法获取itertools.combinations对象中的元素数量。

有什么办法可以做到这一点吗?

Mar*_*ers 6

只需产生随机组合,跟踪您之前见过的内容:

def random_combinations(matrix, size):
    seen = set()
    n = len(matrix)
    while True:
        new_sample = tuple(sorted(random.sample(xrange(n), size)))
        if new_sample not in seen:
            seen.add(new_sample)
            yield tuple(matrix[i] for i in new_sample)
Run Code Online (Sandbox Code Playgroud)

迭代所有可能的组合进行采样的效率并不高,您最终仍会测试所有 10^14 种组合。

每次迭代时,上面的生成器都会选择一个随机组合;如果您需要某个数字,请使用循环或itertools.islice(); 随机选择 10 个组合将是:

combinations_sample = list(islice(random_combinations(matrix, 50), 10))
Run Code Online (Sandbox Code Playgroud)

您可能误解了您找到的函数的作用;它的功能与我上面的函数非常相似,但只生成一个随机组合,而不跟踪之前生成的内容。您应该在 的所有组合上使用它matrix,而不是在 的所有组合上使用它matrix