【问题标题】:Numpy Array to base64 and back to Numpy Array - PythonNumpy 数组到 base64 并返回到 Numpy 数组 - Python
【发布时间】:2011-09-23 01:38:57
【问题描述】:

我现在正试图弄清楚如何从 base64 数据中恢复一个 numpy 数组。这个问题和答案表明这是可能的:Reading numpy arrays outside of Python 但没有给出示例。

以下面的代码为例,如果我知道数组的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 = ????? 

我想要一个 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( ????

我问的原因是因为我正在做一个项目,我想在一个由 django 提供支持的应用程序中的 MySQL 数据库中存储大量 Numpy 数组。

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

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

感谢您的帮助。

【问题讨论】:

    标签: python django arrays numpy base64


    【解决方案1】:
    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
    

    【讨论】:

    • 我还要补充一点,我已经通过应用 q = np.reshape(q,(m,n)) 对多维数组进行了这项工作,其中 m 和 n 的原始尺寸是t 数组。
    • 多维数组处理让我措手不及——b64encode 正在返回多维数组的结果,但这些数组不包含“内部”数组......可怕。感谢大神指点!
    • 只是回到这里添加另一个警告(因为我刚刚被这个咬了)。请注意您的 numpy dtype 是否不是 float64。例如,如果您的源 numpy 数组仅包含整数,则上面的代码将愉快地对其进行编码和解码。但最终结果将是完全错误的,并且不会有任何警告(我知道我应该小心,但是会发生无声错误并且令人讨厌/危险)。 :-/
    • q = np.frombuffer(r, dtype=np.int32) 中使用的“解码”dtype 必须与传递给base64.b64encode(t) 的原始数组t = np.arange(25, dtype=np.int32) 的dtype 匹配。 float64 本身并没有什么特别之处。
    【解决方案2】:

    下面的代码会将其编码为 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"))
    

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

    【讨论】:

      猜你喜欢
      • 2017-12-19
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多