Numpy Array到base64并返回到Numpy Array - Python

seq*_*oia 29 python arrays django base64 numpy

我现在试图弄清楚如何从base64数据中恢复numpy数组.这个问题和答案表明它是可能的:在Python之外读取numpy数组但是没有给出一个例子.

以下面的代码为例,如果我知道dtype和数组的形状,如何从base64数据中获取Numpy数组?

import base64
import numpy as np

t = np.arange(25, dtype=np.float64)
s = base64.b64encode(t)
r = base64.decodestring(s)
q = ????? 
Run Code Online (Sandbox Code Playgroud)

我想要一个python语句将q设置为dtype float64的numpy数组,因此结果是一个与t相同的数组.这是数组编码和解码的样子:

>>> t = np.arange(25,dtype=np.float64)
>>> t
array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
    11.,  12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.,  20.,  21.,
    22.,  23.,  24.])
>>> s=base64.b64encode(t)
>>> s
'AAAAAAAAAAAAAAAAAADwPwAAAAAAAABAAAAAAAAACEAAAAAAAAAQQAAAAAAAABRAAAAAAAAAGEAAAAAAAAAcQAAAAAAAACBAAAAAAAAAIkAAAAAAAAAkQAAAAAAAACZAAAAAAAAAKEAAAAAAAAAqQAAAAAAAACxAAAAAAAAALkAAAAAAAAAwQAAAAAAAADFAAAAAAAAAMkAAAAAAAAAzQAAAAAAAADRAAAAAAAAANUAAAAAAAAA2QAAAAAAAADdAAAAAAAAAOEA='
>>> r = base64.decodestring(s)
>>> r
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00"@\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00&@\x00\x00\x00\x00\x00\x00(@\x00\x00\x00\x00\x00\x00*@\x00\x00\x00\x00\x00\x00,@\x00\x00\x00\x00\x00\x00.@\x00\x00\x00\x00\x00\x000@\x00\x00\x00\x00\x00\x001@\x00\x00\x00\x00\x00\x002@\x00\x00\x00\x00\x00\x003@\x00\x00\x00\x00\x00\x004@\x00\x00\x00\x00\x00\x005@\x00\x00\x00\x00\x00\x006@\x00\x00\x00\x00\x00\x007@\x00\x00\x00\x00\x00\x008@'
>>> q = np.array( ????
Run Code Online (Sandbox Code Playgroud)

我问的原因是因为我正在开发一个项目,我想在一个由django驱动的应用程序中的MySQL数据库中存储很多Numpy数组.

使用这个django片段,我可以在文本字段中存储base64数据:http://djangosnippets.org/snippets/1669/

我想将数组作为base64写入数据库,而不是将数组转换为unicode字符串.

谢谢你的帮助.

unu*_*tbu 39

import base64
import numpy as np

t = np.arange(25, dtype=np.float64)
s = base64.b64encode(t)
r = base64.decodebytes(s)
q = np.frombuffer(r, dtype=np.float64)

print(np.allclose(q, t))
# True
Run Code Online (Sandbox Code Playgroud)

  • `q = np.frombuffer(r, dtype=np.int32)` 中使用的“解码” dtype 必须与原始数组的 dtype 匹配,即 `t = np.arange(25, dtype=np.int32)`传递给`base64.b64encode(t)`。`float64` 本身没有什么特别之处。 (5认同)
  • 我还要补充一点,我已经通过应用q = np.reshape(q,(m,n))为多维数组做了这项工作,其中m和n是t数组的原始维度. (3认同)
  • 多维数组处理让我措手不及——b64encode 正在返回多维数组的结果,但这些数组不包含“内部”数组......可怕。感谢伟大的指点! (3认同)
  • 刚刚回到这里再加上一个警告(因为我刚被这个人咬了).注意你的numpy dtype是不是float64.例如,如果你的source numpy数组只包含int,那么上面的代码将很乐意对它进行编码和解码.但最终的结果将是完全错误的,并且没有警告(我明白我应该小心,但是发生了无声的错误并且很烦人/危险).: - / (2认同)

Vot*_*fee 6

下面的代码将其编码为 base64。它将处理任何类型/大小的 numpy 数组,而无需记住它是什么。它还将处理其他可以腌制的任意对象。

import numpy as np
import pickle
import codecs

obj = np.random.normal(size=(10, 10))
obj_base64string = codecs.encode(pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL), "base64").decode('latin1')
obj_reconstituted = pickle.loads(codecs.decode(obj_base64string.encode('latin1'), "base64"))
Run Code Online (Sandbox Code Playgroud)

如果您只想要原始字节,您可以删除 .decode('latin1') 和 .encode('latin1') 。

  • 一个缺点是你必须在另一侧解开它(仅从Python),所以它不是一种可以与其他技术互换的格式。由于接收部分不是 python,我不得不转向另一种方法。 (3认同)