2013-07-29 4 views
1

ОК, поэтому у меня есть проблема, с которой мне действительно нужна помощь.Ошибка памяти Python при использовании random.sample()

Моя программа считывает значения из файла pdb и сохраняет эти значения в (array = []). Затем я беру каждую комбинацию из 4 из этой конфигурации сохраненных значений и сохраняю ее в списке, называемом maxcoorlist. Поскольку список комбинаций такой большой, чтобы ускорить работу, я хотел бы просто взять образец из 1000-10000 из этого списка комбинаций. Однако при этом я получаю ошибку памяти на самой строке, которая принимает случайный образец.

MemoryError        Traceback (most recent call last) 
<ipython-input-14-18438997b8c9> in <module>() 
    77  maxcoorlist= itertools.combinations(array,4) 
    78  random.seed(10) 
---> 79  volumesample= random_sample(list(maxcoorlist), 1000) 
    80  vol_list= [side(i) for i in volumesample] 
    81  maxcoor=max(vol_list) 

MemoryError: 

Важно, что я использую random.seed() в этом коде, а также, как я буду принимать другие образцы с семенами.

ответ

1

Как упоминалось в других ответах, вызов list() приводит к выходу из памяти.

Вместо этого сначала переберитесь по maxcoorlist, чтобы узнать его длину. Затем создайте случайные числа в диапазоне [0, length) и добавьте их в индексный набор до тех пор, пока длина индекса не будет равна 1000.

Затем повторите попытку через maxcoorlist и добавьте текущее значение к набору образцов, если текущий index находится в вашем наборе индексов.

EDIT

Оптимизация является непосредственно вычислить длину maxcoorlist вместо перебора над ним:

import math 
n = len(array) 
r = 4 
length = math.factorial(n)/math.factorial(r)/math.factorial(n-r) 
+0

Вы предлагаете петлю над комбинациями для вычисления длины (когда это можно сделать с помощью комбинаторики математически), тогда ge nerating 1000 номеров в этом диапазоне, затем генерируя комбинации снова? –

+0

Да, я добавил обновление по этим строкам. –

+0

Это было полезно, спасибо большое! – user2631970

0
maxcoorlist= itertools.combinations(array,4) 
... 
volumesample= random_sample(list(maxcoorlist), 1000) 

При выполнении volumesample вы строите список всех комбинаций из него ... то отбор проб до 1000 ...

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

from itertools import islice 
volumesample = list(islice(maxcoorlist, 1000)) 

Какой займет первый 1000; вы можете настроить его на каждый n-й или похожий, чтобы получить больше эффекта выборки ...

0

Вы, вероятно, занимаете огромное количество памяти (и времени) с maxcoorlist, и приведение в список удваивает пространство памяти, которое оно занимает. Вероятно, вы должны сгенерировать 1000 случайных комбинаций самостоятельно: выборка 4 элемента в случайном порядке, затем проверить, включена ли эта комбинация в ваш список (сортировать их и использовать this_combination in combination_list. Если combination_list - это set, тогда эта проверка будет O (1))

Таким образом, вы берете столько памяти, сколько вам нужно.

0

как о рефакторинг кода использовать кортеж, а не список, как так:

maxcoorlist= itertools.combinations(array,4) 
random.seed(10) 
volumesample= random.sample(tuple(maxcoorlist), 1000) 
vol_list= [side(i) for i in volumesample] 
maxcoor=max(vol_list) 
+0

Использование 'list' вместо' tuple' здесь не имеет значения ... Оно все равно будет создавать все комбинации в памяти, прежде чем делать выборку –

Смежные вопросы