Ошибки памяти и ограничения списка? - PullRequest
61 голосов
/ 04 апреля 2011

Мне нужно производить большие и большие (очень) матрицы (цепи Маркова) для научных целей. Я выполняю исчисление, которое я помещаю в список из 20301 элемента (= одна строка моей матрицы). Мне нужны все эти данные в памяти, чтобы перейти к следующему шагу Маркова, но я могу хранить их в другом месте (например, в файле), если это необходимо, даже если это замедлит мой обход цепи Маркова. Мой компьютер (научная лаборатория): Биксенон 6 ядер / 12 нитей каждый, 12 ГБ памяти, ОС: win64

  Traceback (most recent call last):
  File "my_file.py", line 247, in <module>
    ListTemp.append(calculus)
MemoryError

Пример результатов исчисления: 9.233747520008198e-102 (да, больше 1/9000)

Ошибка возникает при сохранении 19766-го элемента:

ListTemp[19766]
1.4509421012263216e-103

Если я пойду дальше

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    ListTemp[19767]
IndexError: list index out of range

Таким образом, в этом списке произошла ошибка памяти в цикле 19767 года.

Вопросы:

  1. Есть ли предел памяти для списка? Это «ограничение по списку» или «глобальный лимит на скрипт»?

  2. Как обойти эти ограничения? Есть какие-нибудь возможности?

  3. Поможет ли использовать numpy, python64? Какие ограничения памяти у них? Какие о других языках?

Ответы [ 4 ]

52 голосов
/ 04 апреля 2011

Прежде всего, смотрите Насколько большим может получить массив Python? и Numpy, проблема с длинными массивами

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

  1. Если вы работаете в более старой ОС или системе, которая вынуждает процессы использовать ограниченный объем памяти, вам может потребоваться увеличить объем памяти, к которому процесс Python имеет доступ.
  2. Разбейте список на части, используя чанкинг. Например, выполните первые 1000 элементов списка, выберите и сохраните их на диск, а затем выполните следующие 1000. Чтобы работать с ними, извлекайте по одному куску за раз, чтобы не было нехватки памяти. По сути, это тот же метод, который используют базы данных для работы с большим количеством данных, чем умещается в ОЗУ.
25 голосов
/ 04 апреля 2011

Исключение MemoryError, которое вы видите, является прямым результатом нехватки доступной оперативной памяти.Это может быть вызвано либо ограничением в 2 ГБ на программу, установленным Windows ( 32-битные программы ), либо отсутствием доступной оперативной памяти на вашем компьютере.(Эта ссылка относится к предыдущему вопросу).

Вы сможете расширить 2 ГБ, используя 64-битную копию Python, при условии, что вы используете 64-битную копию Windows.

IndexError будет вызвано тем, что Python включил исключение MemoryError перед вычислением всего массива.Опять же, это проблема памяти.

Чтобы обойти эту проблему, вы можете попробовать использовать 64-битную копию Python или, что еще лучше, найти способ записи результатов в файл.С этой целью посмотрите на сопоставленные массивы памяти numpy .

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

7 голосов
/ 04 апреля 2011

Python не ограничивает память. Тем не менее, вы получите MemoryError, если у вас не хватает оперативной памяти. Вы говорите, что у вас есть 20301 элемент в list. Это кажется слишком маленьким, чтобы вызвать ошибку памяти для простых типов данных (например, int), но если каждый элемент сам по себе является объектом, который занимает много памяти, у вас вполне может быть недостаточно памяти.

Однако IndexError, вероятно, вызвано тем, что в вашем ListTemp есть только 19767 элементов (с индексом от 0 до 19766), и вы пытаетесь получить доступ к последнему элементу.

Трудно сказать, что вы можете сделать, чтобы избежать превышения предела, не зная точно, что именно вы пытаетесь сделать. Использование numpy может помочь. Похоже, вы храните огромное количество данных. Возможно, вам не нужно хранить все это на каждом этапе. Но невозможно сказать, не зная.

0 голосов
/ 30 марта 2018

Если вы хотите обойти эту проблему, вы также можете воспользоваться полкой. Затем вы создадите файлы, которые будут соответствовать размеру вашей машины, и будут помещать их в ОЗУ только при необходимости, в основном записывая на HD и собирая информацию по частям, чтобы вы могли обработать ее.

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

Data = shelve.open('File01')
   for i in range(0,100):
     Matrix_Shelve = 'Matrix' + str(i)
     if Matrix_Shelve in Data:
        Matrix_local = Data[Matrix_Shelve]
     else:
        Data[Matrix_Selve] = 'somenthingforlater'

Надеюсь, это не звучит слишком по-английски.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...