Вопрос

Вопрос Python. Я генерирую большой массив объектов, которые мне нужно только сделать небольшой случайный образец. На самом деле генерация рассматриваемых объектов требуется некоторое время, поэтому мне интересно, можно ли как-то пропустить эти объекты, которые не нуждаются в генерации, и только явно создают эти объекты, которые были выбраны.

Другими словами, у меня сейчас есть

a = createHugeArray()
s = random.sample(a,len(a)*0.001)

что довольно расточительно. Я бы предпочел что-то более ленивое

a = createArrayGenerator()
s = random.sample(a,len(a)*0.001)

Я не знаю, работает ли это. Документация по случайной. Наплете не слишком понятно, хотя он упоминает xRange как очень быстро - что заставляет меня поверить, что это может работать. Преобразование создания массива на генератор было бы немного работы (мои знания генераторов очень ржавы), поэтому я хочу знать, заранее ли это работает. :)

Альтернатива, которую я могу видеть, это сделать случайный образец через xrange и генерировать только эти объекты, которые фактически выбраны индексом. Это не очень чисто, потому что, поскольку, поскольку индексы, созданные произвольными и ненужными, и мне понадобится довольно хаки, чтобы поддержать это в моем методе GenerateHugearray.

Для бонусных баллов: как дела в случайном порядке. Особенно, как это работает, если она не знает размера населения заранее, как с генераторами, как xrange?

Это было полезно?

Решение

Не похоже, что позволяет избежать того, как индексы отображают свои перестановки. Если вы этого не знаете, как бы вы создали случайный объект из вашего массива? Вы могли бы либо использовать трюк, используя xrange() Вы предложили себе или внедрить класс, определяющий __getitem__() и __len__() Методы и пропуск и объект этого класса как population аргумент random.sample().

Некоторые дополнительные комментарии:

  • Преобразование createhugearray () в генератор ничего не купит вам random.sample() просто не будет работать больше. Ему нужен поддерживающий объект len().

  • Так что делает Нужно знать количество элементов в населении прямо с самого начала.

  • То реализация Особенности двух разных алгоритмов и выбирает тот, который будет использовать меньше памяти. Для относительно мало k (то есть в случае под рукой) он просто сохранит индексы, уже выбранные в set и сделать новый случайный выбор, если он попадает в одно из них.

Редактировать: совершенно другой подход будет повторять все перестановки один раз и решить для каждой перестановки, если оно должно быть включено. Если общее количество перестановок n и вы хотели бы выбрать k из них, вы могли бы написать

selected = []
for i in xrange(n):
    perm = nextPermutation()
    if random.random() < float(k-len(selected))/(n-i):
        selected.append(perm)

Это выбрало бы точно k Перестановки случайным образом.

Другие советы

Вы можете создать список индексов массива с образцом, а затем генерировать объекты в соответствии с результатами:

def get_object(index):
    return MyClass(index)

Или что-то вроде этого. Затем используйте образец для создания необходимых индексов и вызовите эту функцию с этими показателями:

objs = map(get_object, random.sample(range(length), 0.001 * length))

Это немного косвенно, так как в нем выбирается только из списка возможных индексов массива.

Объясняя, как работает Random.sample,

random.sample(container, k) Возвращаю K ряд значений случайным образом из контейнера. Поскольку генератор является истечением, как списки, кортежи и клавиши или значения в диктографиях, которые он повторяет через контейнер, а затем принимает эти случайные элементы.

например random.sample(xrange(111),4) вернется что-то вроде [33,52,111,1] в виде k = 4 Значение 4 случайных числа из генератора Xrange до 111.

Я предполагаю, что функция CreateHugearRay () содержит кусок кода, который повторяется один раз для каждого созданного объекта. И я предполагаю, что объекты генерируются из какого-то начального значения или семян, в каком случае CreateHugearray () выглядит что-то вроде этого:

def createHugeArray( list_of_seeds ):
  huge_array = []                  
  for i in list_of_seeds:
    my_object = makeObject( i )
    huge_array.append( my_object )           
  return huge_array

(Я использовал списки не массивов, но вы получаете идею.)

Чтобы выполнить случайную выборку, прежде чем на самом деле создать объекты, просто добавьте строку, которая генерирует случайное число, а затем только создать объект, если случайное число ниже определенного порога. Скажи, что вы хотите только один объект в тысячу. Random.randint (0999) дает номер от 0 до 999 - поэтому только генерируют объект, если вы получаете ноль. Код выше становится:

import random

def createHugeArray( list_of_seeds ):
  huge_array = [] 

  for i in list_of_seeds:
    die_roll = random.randint(0,999)

    if( die_roll == 0 ):
      my_object = makeObject( i )
      huge_array.append( my_object ) 
  return huge_array

Конечно, если мое предположение о том, как ваш код работает неправильно, то это бесполезно вам, в каком случае извините и удачи :-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top