使用 Flask 保存和发送大型 numpy 数组

A. *_*tia 1 python numpy flask h5py

我正在寻找通过 Flask 发送大型 Numpy 数组(主要由图像组成)的最佳方式。

现在,我现在正在做这样的事情:

服务器端:

np.save(matrix_path, my_array)
return send_file(matrix_path+'.npy') 
Run Code Online (Sandbox Code Playgroud)

客户端:

with open('test_temp', 'wb') as f:
    f.write(r.content)
my_array = np.load('test_temp')
Run Code Online (Sandbox Code Playgroud)

但是 .npy 文件非常大,所以需要很长时间。

我想过使用 h5py 但由于图像具有不同的大小 ( array.shape = (200,)),我不能使用 h5py(为每个图像创建一个数据集会太长)。

有没有人知道如何优化它?

Aar*_*ron 5

由于评论部分本身才刚刚开始成为一个答案,我会在这里写出来。

编辑: 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)
Run Code Online (Sandbox Code Playgroud)

有 3 种快速方法可以提高发送文件的速度。

  1. 不要写入磁盘:这个非常简单,只需在将数据传递给之前使用缓冲区存储数据 flask.send_file()
  2. 压缩数据:一旦你有一个二进制数据缓冲区,有很多压缩选项,但它zlib是标准 python 发行版的一部分。如果您的数组是图像(或者即使它们不是),png 压缩是无损的,有时可以提供比 zlib 更好的压缩。Scipy 正在贬低它的内置功能imreadimwrite因此您imageio.imwrite现在应该使用它。
  3. 获得更高性能的服务器来实际执行文件发送。当您app.run()直接($flask run$python -m flask run)通过flask调用或调用您的应用程序时,调用的内置开发服务器不支持X-Sendfile 功能。这是在 Apache 或 Nginx 之类的东西后面运行 Flask 的原因之一。不幸的是,这对于每个服务器的实现方式并不相同,并且可能需要文件系统中的文件(尽管如果操作系统支持,您可能会使用内存文件)。对于您选择的任何部署,这都是 rtfm 的情况。