我正在寻找通过 Flask 发送大型 Numpy 数组(主要由图像组成)的最佳方法。
现在,我正在做这样的事情:
服务器端:
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(为每个图像创建数据集太长)。
有人知道如何优化它吗?
最佳答案
由于评论部分本身才刚刚开始成为答案,因此我会将其全部写在这里。
编辑: numpy 有一种内置方法可以将多个数组压缩到一个文件中,以便将它们整齐地打包以便发送。与使用缓冲区而不是磁盘上的文件相结合可能是获得一定速度的最快且最简单的方法。以下是 numpy.savez_compressed
将一些数据保存到缓冲区的简单示例,以及 this question显示使用 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 种快速方法可以提高发送文件的速度。
- 不写入磁盘:这非常简单,只需使用缓冲区来存储数据,然后将其传递给
flask.send_file()
- 压缩数据:一旦有了二进制数据缓冲区,就有很多压缩选项,但是
zlib
是标准 python 发行版的一部分。如果您的数组是图像(或者即使不是),png compression是无损的,有时可以提供比 zlib 本身更好的压缩。 Scipy 正在弃用它的内置imread
和imwrite
因此您应该使用imageio.imwrite
现在。 - 获取更高性能的服务器来实际执行文件发送。当您调用
app.run()
或直接通过flask调用您的应用程序时调用的内置开发服务器($flask run
或$python -mflask run
) 不支持 X-Sendfile 功能。这是在 Apache 或 Nginx 等程序后面运行 Flask 的原因之一。不幸的是,这对于每个服务器来说并不是以相同的方式实现的,并且可能需要文件系统中的文件(尽管如果操作系统支持的话,您可以使用内存中的文件)。无论您选择哪种部署,这都将是 rtfm 的情况。
关于python - 使用 Flask 保存并发送大型 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55301037/