Уменьшить объем памяти для массива numpy - PullRequest
0 голосов
/ 04 мая 2020

Я создаю набор оконных данных для глубокого изучения. Я сгенерировал данные как numpy массивы 4 массива с формой (141038, 360) и 1 массив для меток формы (141038,). Я сохранил массивы в файле npz, но размер файла слишком велик - 1,5 ГБ. Я новичок в python и программировании, поэтому понятия не имею, насколько большим должен быть размер файла. Однако я преобразовал массивы в Pandas фреймы данных, и использование памяти было в том же диапазоне. Проблема в том, что у меня есть 6 файлов с 9 ГБ и, возможно, другой набор данных с перекрытием, которое в 7 раз больше, поэтому возможно будет 63 ГБ.

  • Является ли такой размер файла реалистичным c или я что то не так сделал? (это просто файл с некоторыми цифрами, а не игра)

  • Есть ли другой формат для сохранения моих массивов с меньшим использованием памяти? (Я попробовал HFD5, но получил тот же размер файла)

  • Я попытался изменить типы данных, и он немного уменьшил размер. (3 массива (f8), 1 (int8), 1 (uint8)) есть ли другие типы данных, которые могли бы уменьшить размер больше? для значений 0/1 есть ли другой тип данных, более эффективный, чем (uint)?

  • Для массивов с плавающей запятой, если я уменьшу точность, это поможет? или есть другой способ уменьшить их размер?

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

1 Ответ

1 голос
/ 04 мая 2020
  1. Да, если вы используете данные типа с плавающей запятой, это определенно так.

  2. Вы можете попробовать numpy.savez_compressed сохранить как сжатый массив.

ref: https://docs.scipy.org/doc/numpy/reference/generated/numpy.savez_compressed.html

Вы также можете использовать gzip, но алгоритм сжатия важен.

import gzip
import numpy

f = gzip.GzipFile("x.npy.gz", "w")
numpy.save(file=f, arr=x)
f.close()

это может быть полезно: Сжатие numpy Массивы эффективно

Для двоичных данных uint8 кажется большой тратой. Фактически, вы можете хранить 8 значений (0/1) в одном uin8. Просто считайте 0, 1 битами, и вы можете кодировать 8 бит в одном uint8 с помощью простых двоичных операций.

Вы можете использовать «логическое значение» для хранения значений 0/1.

import numpy as np
import sys

b = np.array([0, 1, 0]*50000, dtype='b')

print(sys.getsizeof(b))

u8 = np.array([0, 1, 0]*50000, dtype='u8')

print(sys.getsizeof(u8))
150096
1200096

Да, определенно. Если вы рассматриваете сжатие с потерями как вариант, вы можете сжать массив с хорошим коэффициентом.

Не имеет значения, важны только форма и типы данных. Numpy массивы не сжимаются. Если вы сравните его с изображениями - это было бы неправильно, аналогия типа «черное изображение имеет меньший размер из-за однородности, поэтому массивы с нулевой подкладкой должны занимать меньше места» - не имеет значения (изображения обычно сжимают JPEG с потерями).

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