生成大的随机序列的唯一数字

war*_*iuc 13 python random

我需要填写一个文件,其中包含许多由数字标识的记录(测试数据).记录的数量非常大,而且ID应该是唯一的,记录的顺序应该是随机的(或伪随机的).

我试过这个:

# coding: utf-8
import random

COUNT = 100000000

random.seed(0)
file_1 = open('file1', 'w')
for i in random.sample(xrange(COUNT), COUNT):
    file_1.write('ID{0},A{0}\n'.format(i))
file_1.close()
Run Code Online (Sandbox Code Playgroud)

但它正在吃掉我所有的记忆.

有没有办法生成一个连续的大洗牌序列(不一定但它会很好,否则是唯一的)整数?使用发生器而不是将所有序列保留在RAM中?

Eri*_*got 9

如果您在问题中有1亿个数字,那么这实际上可以在内存中管理(大约需要0.5 GB).

正如DSM所指出的那样,这可以通过标准模块以有效的方式完成:

>>> import array
>>> a = array.array('I', xrange(10**8))  # a.itemsize indicates 4 bytes per element => about 0.5 GB
>>> import random                                                               
>>> random.shuffle(a)
Run Code Online (Sandbox Code Playgroud)

也可以使用第三方NumPy包,它是用于以有效方式管理数组的标准Python工具:

>>> import numpy
>>> ids = numpy.arange(100000000, dtype='uint32')  # 32 bits is enough for numbers up to about 4 billion
>>> numpy.random.shuffle(ids)
Run Code Online (Sandbox Code Playgroud)

(这仅在您的程序已经使用NumPy时才有用,因为标准模块方法效率很高).


这两种方法在我的机器上花费大约相同的时间(可能是1分钟的洗牌),但是它们使用的0.5 GB对于当前的计算机来说并不是太大.

PS:改组的元素太多,实际上是随机的,因为与使用的随机生成器的周期相比,存在太多可能的排列.换句话说,Python shuffle比可能的shuffle数量少!

  • 即使没有'numpy`,我认为`a = array.array('我',xrange(10**8))`和`random.shuffle(a)`也会达到同样的目的.如果N足够小,这是远离目标的最简单路线. (2认同)
  • mersenne twister`random`使用的时间为2 ^ 19937 - 1(根据维基百科).如果我没有弄乱摆弄Wolfram alpha(它拒绝直接评估这些,所以我不得不使用Stirling的近似值),1亿!大概是2 ^(10 ^ 9.4),所以你的PS是正确的.这段时期仍然令人印象深刻. (2认同)