Генерировать большую случайную последовательность уникальных чисел

Мне нужно заполнить файл большим количеством записей, идентифицированных номером (тестовые данные). Количество записей очень велико, и идентификаторы должны быть уникальными, а порядок записей должен быть случайным (или псевдослучайным).

Я попробовал это:

# 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() 

Но он все испортил мне.

Есть ли способ генерировать большую перетасованную последовательность последовательных (не обязательно, но это было бы неплохо, иначе уникально) целые числа? Используя генератор и не сохраняя всю последовательность в ОЗУ?

4 Solutions collect form web for “Генерировать большую случайную последовательность уникальных чисел”

Если у вас есть 100 миллионов номеров, как в вопросе, то это фактически управляемое в памяти (оно занимает около 0,5 ГБ).

Как отметил 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) 

Также возможно использовать сторонний пакет 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) 

(это полезно, только если ваша программа уже использует NumPy, так как стандартный модульный подход примерно такой же эффективный).


Оба метода занимают примерно такое же количество времени на моей машине (возможно, 1 минуту для перетасовки), но 0,5 ГБ, которые они используют, не слишком велики для текущих компьютеров.

PS : Слишком много элементов для перетасовки, чтобы быть действительно случайным, потому что существует слишком много перестановок по сравнению с периодом используемых случайных генераторов. Другими словами, количество перетасовки Python меньше, чем количество возможных перетасовки!

Может быть, что-то вроде (не будет последовательным, но будет уникальным):

 from uuid import uuid4 def unique_nums(): # Not strictly unique, but *practically* unique while True: yield int(uuid4().hex, 16) # alternative yield uuid4().int unique_num = unique_nums() next(unique_num) next(unique_num) # etc... 

Вы можете легко получить случайный int из чтения (по linux) /dev/urandom или используя os.urandom() и struct.unpack() :

Возвращает строку из n случайных байтов, подходящих для использования в криптографии.

Эта функция возвращает случайные байты из источника случайности, специфичного для ОС. Возвращенные данные должны быть непредсказуемыми для криптографических приложений, хотя его точное качество зависит от реализации ОС. В UNIX-подобной системе это будет запрашивать / dev / urandom , а в Windows – использовать CryptGenRandom . Если источник случайности не найден, NotImplementedError будет поднят.

 >>> for i in range(4): print( hex( struct.unpack('<L', os.urandom(4))[0])) ... 0xbd7b6def 0xd3ecf2e6 0xf570b955 0xe30babb6 

В то время как, с другой стороны, random пакет:

Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографических целей.

Если вам действительно нужны уникальные записи, вы должны пойти с этим или ответить предоставленным EOL .

Но если предположить, что действительно случайный источник, возможно, с повторяющимися символами, у вас будет 1/N (где N = 2 ** sizeof(int)*8 = 2 ** 32 ) вероятность попадания предмета при первой догадке, таким образом вы можете получить (2**32) ** length возможных выходов.

С другой стороны, при использовании только уникальных результатов вы получите max :

 product from i = 0 to length {2*32 - i} = n! / (n-length)! = (2**32)! / (2**32-length)! 

Где ! является факториальным, а не логическим отрицанием. Таким образом, вы просто уменьшите случайность результата.

Это сохранит вашу память в порядке, но, возможно, убьет ваш диск 🙂

Он генерирует файл с порядком чисел от 0 до 100000000, а затем он произвольно выбирает позиции в нем и записывает в другой файл. Цифры должны быть реорганизованы в первом файле для «удаления» уже выбранных номеров.

 import random COUNT = 100000000 # Feed the file with open('file1','w') as f: i = 0 while i <= COUNT: f.write("{0:08d}".format(i)) i += 1 with open('file1','r+') as f1: i = COUNT with open('file2','w') as f2: while i >= 0: f1.seek(i*8) # Read the last val last_val = f1.read(8) random_pos = random.randint(0, i) # Read random pos f1.seek(random_pos*8) random_val = f1.read(8) f2.write('ID{0},A{0}\n'.format(random_val)) # Write the last value to this position f1.seek(random_pos*8) f1.write(last_val) i -= 1 print "Done" 
  • random.sample () каждый раз возвращает одну и ту же случайную последовательность?
  • Python удаляет элемент из случайного списка, после его выбора
  • почему моя математическая викторина всегда печатает неправильно, когда ответ правильный
  • Как я могу генерировать случайные числа в Python?
  • Python - случайная выборка из диапазона, избегая определенных значений
  • Случайная последовательность Python с семенем
  • Генератор случайных выборок
  • Случайные строки Python из подпапок
  •  
    Interesting Posts for Van-Lav

    Найти индексы всех совпадений регулярных выражений в Python?

    Операция Redshift COPY не работает в SQLAlchemy

    Извлечь все файлы с каталогом в заданной директории

    Исключение с плавающей точкой с помощью Numpy и PyTables

    не удалось удалить исходную точку в polyplollection matplotlib

    как сохранить размер pcolormesh в виде массива numpy – сохраняя форму данных?

    Улучшить производительность функции без распараллеливания

    Как удалить столбец из структурированного массива numpy?

    как удалить AttributeError в Robobrowser

    Проверьте и подождите, пока файл не будет прочитан.

    Итерировать строку формата над списком

    Как импортировать данные из разных типов из массива в массив Python Numpy?

    Stop ConfigParser добавляет пробелы в delims после обновления с python 2.7.3 до 2.7.9

    python использует неверный префикс пространства имен в запросе SOAP

    Функция обратного вызова при каждом нажатии клавиши (независимо от того, какое окно имеет фокус)?

    Python - лучший язык программирования в мире.