Очень большие матрицы с использованием Python и NumPy

NumPy - чрезвычайно полезная библиотека, и из ее использования я обнаружил, что он способен обрабатывать матрицы, которые довольно большие ( 10000 x 10000) легко, но начинает бороться с чем-то большим (попытка создать матрицу размером 50000 x 50000). Очевидно, это связано с огромными требованиями к памяти.

Есть ли способ создать огромные матрицы изначально в NumPy (скажем, 1 миллион на 1 миллион) в некотором роде (без нескольких терабайтов ОЗУ)?

Ответ 1

PyTables и NumPy - это путь.

PyTables будет хранить данные на диске в формате HDF с дополнительным сжатием. Мои наборы данных часто получают сжатие 10x, что удобно при работе с десятками или сотнями миллионов строк. Это также очень быстро; мой 5-летний ноутбук может хрустнуть через данные, выполняющие SQL-подобную агрегацию GROUP BY со скоростью 1 000 000 строк в секунду. Неплохо для решения на основе Python!

Доступ к данным в качестве повторной записи NumPy выполняется так же просто, как:

data = table[row_from:row_to]

Библиотека HDF позаботится о чтении в соответствующих кусках данных и преобразовании в NumPy.

Ответ 2

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

  • Попробуйте более эффективное представление матрицы, которое использует любую специальную структуру, которую имеют ваши матрицы. Например, как уже отмечали другие, существуют эффективные структуры данных для разреженных матриц (матрицы с большим количеством нулей), например scipy.sparse.csc_matrix.
  • Измените свой алгоритм работы с подматрицами. Вы можете читать с диска только матричные блоки, которые в настоящее время используются в вычислениях. Алгоритмы, предназначенные для работы на кластерах, обычно работают поблочно, поскольку данные обрываются на разных компьютерах и передаются только тогда, когда это необходимо. Например, алгоритм Fox для матричного умножения (файл PDF).

Ответ 3

Вы должны иметь возможность использовать numpy.memmap для карты памяти на диске. С новым python и 64-разрядной машиной вы должны иметь необходимое адресное пространство, не загружая все в память. ОС должна обрабатывать только часть файла в памяти.

Ответ 4

Для обработки разреженных матриц вам понадобится пакет scipy, который находится поверх numpy - см. здесь для получения более подробной информации о варианты разреженной матрицы, которые scipy дает вам.

Ответ 5

Стефано Борини сообщение заставлял меня заглядывать, как далеко по этому поводу уже есть.

Это он. Кажется, в основном, что вы хотите. HDF5 позволит вам хранить очень большие наборы данных, а затем использовать и использовать их одинаково, как это делает NumPy.

Ответ 6

Убедитесь, что вы используете 64-разрядную операционную систему и 64-разрядную версию Python/NumPy. Обратите внимание, что на 32-битных архитектурах вы можете обращаться, как правило, на 3 ГБ памяти (с примерно 1 ГБ, потерянным для ввода/вывода с памятью и т.д.).

С 64-битными и массивами вещей, большими, чем доступная оперативная память, вы можете уйти с виртуальной памятью, хотя все будет медленнее, если вам придется поменять местами. Кроме того, карты памяти (см. Numpy.memmap) - это способ работы с огромными файлами на диске без их загрузки в память, но для этого вам нужно иметь 64-разрядное адресное пространство для этого. PyTables будет делать большую часть этого и для вас.

Ответ 7

Это немного альфа, но http://blaze.pydata.org/, похоже, работает над решением этого.

Ответ 8

Вы спрашиваете, как обрабатывать матрицу элементов размером 2 500 000 000 без терабайт ОЗУ?

Способ обработки 2 миллиардов элементов без 8 миллиардов байт ОЗУ - это не сохранение матрицы в памяти.

Это означает гораздо более сложные алгоритмы для извлечения его из файловой системы в куски.

Ответ 9

Иногда одно простое решение использует настраиваемый тип для ваших элементов матрицы. Основываясь на диапазоне номеров, которые вам нужны, вы можете использовать руководство dtype и особенно меньше для своих товаров. Поскольку Numpy считает самый большой тип объекта по умолчанию, это может быть полезной идеей во многих случаях. Вот пример:

In [70]: a = np.arange(5)

In [71]: a[0].dtype
Out[71]: dtype('int64')

In [72]: a.nbytes
Out[72]: 40

In [73]: a = np.arange(0, 2, 0.5)

In [74]: a[0].dtype
Out[74]: dtype('float64')

In [75]: a.nbytes
Out[75]: 32

И с настраиваемым типом:

In [80]: a = np.arange(5, dtype=np.int8)

In [81]: a.nbytes
Out[81]: 5

In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)

In [78]: a.nbytes
Out[78]: 8

Ответ 10

Обычно, когда мы имеем дело с большими матрицами, мы реализуем их как Разреженные матрицы.

Я не знаю, поддерживает ли numpy разреженные матрицы, но я нашел this вместо этого.

Ответ 11

Насколько я знаю о numpy, нет, но я мог ошибаться.

Я могу предложить вам это альтернативное решение: написать матрицу на диске и получить доступ к ней в кусках. Я предлагаю вам формат файла HDF5. Если вам это нужно прозрачно, вы можете переопределить интерфейс ndarray, чтобы разбивать вашу память на диск в память. Будьте осторожны, если вы измените данные, чтобы синхронизировать их на диске.

Ответ 12

Вы можете запустить свой код в Google Colab. Google Colab - это бесплатный облачный сервис, и теперь он поддерживает бесплатный графический процессор! Я мог бы построить (870199 * 14425) матрицу в Google Colab которую не смог запустить на своем ПК.