Ошибки памяти и ограничения списка?


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

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

Пример результатов вычислений: 9.233747520008198 e-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 50

4 ответа:

Во-первых, смотрите Насколько большим может быть массив Python? и Numpy, задача с длинными массивами

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

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

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

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

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

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

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

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

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

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

Если вы хотите обойти эту проблему, вы также можете использовать стеллаж. Затем вы создадите файлы, размер которых будет соответствовать емкости вашей машины, и только при необходимости поместите их в оперативную память, в основном записывая на 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'

Надеюсь, что нет. звучит слишком архаично.