Подтвердить что ты не робот

Ошибки памяти и лимиты списков?

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

Вопросы:

  • Есть ли предел памяти для списка? Является ли это "лимитом по списку" или "global-per- script limit"?

  • Как обойти эти ограничения? Любые возможности в виду?

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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