Сохраняйте и отправляйте большие массивы с помощью Flask - PullRequest
0 голосов
/ 22 марта 2019

Я ищу лучший способ отправки больших массивов Numpy (состоящих в основном из изображений) через Flask.

Сейчас я делаю что-то вроде этого:

На стороне сервера:

np.save(matrix_path, my_array)
return send_file(matrix_path+'.npy') 

На стороне клиента:

with open('test_temp', 'wb') as f:
    f.write(r.content)
my_array = np.load('test_temp')

Но.Файл npy очень большой, поэтому занимает слишком много времени.

Я думал об использовании h5py, но поскольку изображения имеют разный размер (array.shape = (200,)), я не могу использовать h5py (создание набора данных для каждого изображения будет слишком длинным).

Кто-нибудь получитидея как это оптимизировать?

1 Ответ

0 голосов
/ 22 марта 2019

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

РЕДАКТИРОВАТЬ: numpy имеет встроенный способсжать несколько массивов в файл, чтобы аккуратно упаковать их для отправки.В сочетании с использованием буфера, а не файла на диске, это, вероятно, самый быстрый и простой способ получить некоторую скорость.Вот быстрый пример numpy.savez_compressed сохранения некоторых данных в буфер, и этот вопрос показывает отправку буфера с использованием flask.send_file

import numpy as np
import io

myarray_1 = np.arange(10) #dummy data
myarray_2 = np.eye(5)

buf = io.BytesIO() #create our buffer
#pass the buffer as you would an open file object
np.savez_compressed(buf, myarray_1, myarray_2, #etc...
         )

buf.seek(0) #This simulates closing the file and re-opening it.
            #  Otherwise the cursor will already be at the end of the
            #  file when flask tries to read the contents, and it will
            #  think the file is empty.

#flask.sendfile(buf)

#client receives buf
npzfile = np.load(buf)
print(npzfile['arr_0']) #default names are given unless you use keywords to name your arrays
print(npzfile['arr_1']) #  such as: np.savez(buf, x = myarray_1, y = myarray_2 ... (see the docs)

Есть 3 быстрых способа получить некоторыескорость отправки файлов.

  1. не записывать на диск: это довольно просто, просто используйте буфер для хранения данных, прежде чем передавать их в flask.send_file()
  2. сжиматьdata: если у вас есть буфер двоичных данных, есть много вариантов сжатия, но zlib является частью стандартного дистрибутива Python.Если ваши массивы являются изображениями (или даже если это не так), png компрессия без потерь и иногда может обеспечить лучшее сжатие, чем zlib самостоятельно.Scipy устарел из-за встроенных imread и imwrite, поэтому вы должны использовать imageio.imwrite сейчас.
  3. Получить сервер с более высокой производительностью для фактической отправки файлов.Встроенный сервер разработки, который вызывается при вызове app.run() или при непосредственном вызове приложения через флешку ($flask run или $python -m flask run), не поддерживает функцию X-Sendfile.Это одна из причин использовать флешку за чем-то вроде Apache или Nginx.К сожалению, это не реализовано одинаково для каждого сервера и может потребовать файл в файловой системе (хотя вы можете использовать файл в памяти, если ОС поддерживает его).Это будет случай rtfm для любого развертывания, которое вы выберете.
...