Я ищу быстрый способ сохранить большие массивы numpy. Я хочу сохранить их на диск в двоичном формате, а затем относительно быстро прочитать их обратно в память. К сожалению, cPickle работает недостаточно быстро.
Я нашел numpy.savez и numpy.load . Но странно то, что numpy.load загружает файл npy в «карту памяти». Это означает, что регулярные манипуляции с массивами очень медленные. Например, что-то вроде этого будет очень медленным:
#!/usr/bin/python
import numpy as np;
import time;
from tempfile import TemporaryFile
n = 10000000;
a = np.arange(n)
b = np.arange(n) * 10
c = np.arange(n) * -0.5
file = TemporaryFile()
np.savez(file,a = a, b = b, c = c);
file.seek(0)
t = time.time()
z = np.load(file)
print "loading time = ", time.time() - t
t = time.time()
aa = z['a']
bb = z['b']
cc = z['c']
print "assigning time = ", time.time() - t;
точнее, первая строка будет очень быстрой, но оставшиеся строки, которые присваивают массивы obj
, смехотворно медленные:
loading time = 0.000220775604248
assining time = 2.72940087318
Есть ли лучший способ сохранить массивы numpy? В идеале я хочу иметь возможность хранить несколько массивов в одном файле.
np.load
следует отображать файл.numpy.savez
) по умолчанию массивы загружаются "лениво". Он не запоминает их, но и не загружает, покаNpzFile
объект не проиндексирован. (Таким образом, задержка, о которой идет речь в ОП.) В документацииload
это пропускается, и поэтому она вводит в заблуждение ...Ответы:
Я большой поклонник hdf5 для хранения больших массивов numpy. Есть два варианта работы с hdf5 в python:
http://www.pytables.org/
http://www.h5py.org/
Оба предназначены для эффективной работы с массивами numpy.
источник
Я сравнил производительность (пространство и время) для нескольких способов хранения массивов numpy. Некоторые из них поддерживают несколько массивов на файл, но, возможно, это все равно полезно.
Npy и двоичные файлы очень быстрые и маленькие для плотных данных. Если данные разреженные или очень структурированные, вы можете использовать npz со сжатием, что сэкономит много места, но потребует некоторого времени загрузки.
Если переносимость является проблемой, двоичный файл лучше, чем npy. Если удобочитаемость для человека важна, вам придется пожертвовать большой производительностью, но этого можно довольно хорошо добиться с помощью csv (который, конечно, также очень переносим).
Более подробная информация и код доступны в репозитории github .
источник
binary
лучше, чемnpy
для портативности? Это также относится кnpz
?Теперь существует клон, основанный на HDF5, под
pickle
названиемhickle
!https://github.com/telegraphic/hickle
РЕДАКТИРОВАТЬ:
Также есть возможность «засолить» прямо в сжатый архив, выполнив:
аппендикс
источник
savez () сохраняет данные в zip-архиве. Для архивирования и распаковки файла может потребоваться некоторое время. Вы можете использовать функции save () и load ():
Чтобы сохранить несколько массивов в одном файле, вам просто нужно сначала открыть файл, а затем последовательно сохранить или загрузить массивы.
источник
Еще одна возможность эффективно хранить массивы numpy - это Bloscpack :
и вывод для моего ноутбука (относительно старый MacBook Air с процессором Core2):
это означает, что он может хранить очень быстро, то есть узким местом обычно является диск. Однако, поскольку здесь довольно хорошие степени сжатия, эффективная скорость умножается на степени сжатия. Вот размеры этих массивов 76 МБ:
Обратите внимание, что использование компрессора Blosc имеет решающее значение для достижения этой цели. Тот же сценарий, но с использованием 'clevel' = 0 (т.е. отключение сжатия):
явно ограничено производительностью диска.
источник
Время поиска медленное, потому что когда вы используете
mmap
to, не загружает содержимое массива в память при вызовеload
метода. Когда требуются определенные данные, данные загружаются лениво. И это происходит в вашем случае при поиске. Но второй поиск не будет таким медленным.Это хорошая особенность,
mmap
когда у вас большой массив, вам не нужно загружать все данные в память.Чтобы решить вашу проблему, вы можете использовать joblib, вы можете сбросить любой объект, который хотите, используя
joblib.dump
даже два или болееnumpy arrays
, см. Примеристочник