arrays - 为什么 BSON 序列化的 numpy 数组比原始数组大得多?

标签 arrays python-3.x numpy serialization bson

我正在处理 numpy 数组形式的图像。我需要将它们序列化为 JSON 或从 JSON 反序列化(我使用的是 MongoDB)

numpy数组无法用json.dump序列化;我知道this但我想知道是否有更好的方法,因为将 bytes numpy 数组转换为 BSON 会将字节数乘以几乎 12 (我不明白为什么):

import numpy as np
import bson
from io import StringIO as sio
RC = 500
npdata = np.zeros(shape=(RC,RC,3), dtype='B')
rows, cols, depth = npdata.shape
npsize = rows*cols*depth
npdata=npdata.reshape((npsize,))
listdata = npdata.tolist()
bsondata = bson.BSON.encode({"rows": rows, "cols": cols, "data": listdata})
lb = len(bsondata)
print(lb, npsize, lb/npsize) 

> 8888926 750000 11.851901333333334 

最佳答案

字节数增加的原因是 BSON 保存数据的方式。您可以在 BSON specification 中找到此信息,但让我们看一个具体的例子:

import numpy as np
import bson

npdata = np.arange(5, dtype='B') * 11
listdata = npdata.tolist()
bsondata = bson.BSON.encode({"rows": rows, "cols": cols, "data": listdata})

print([hex(b) for b in bsondata])

在这里,我们将一个值为 [0, 11, 22, 33, 44, 55] 的数组存储为 BSON 并打印生成的二进制数据。下面我对结果进行了注释以解释发生了什么:

['0x47', '0x0', '0x0', '0x0',  # total number of bytes in the document
 # First element in document
     '0x4',  # Array
     '0x64', '0x61', '0x74', '0x61', '0x0',  # key: "data"
     # subdocument (data array)
         '0x4b',  '0x0', '0x0', '0x0',  # total number of bytes
         # first element in data array
             '0x10',                        # 32 bit integer
             '0x30', '0x0',                 # key: "0"
             '0x0', '0x0', '0x0', '0x0',    # value: 0
         # second element in data array
             '0x10',                        # 32 bit integer
             '0x31', '0x0',                 # key: "1"
             '0xb', '0x0', '0x0', '0x0',    # value: 11
         # third element in data array
             '0x10',                        # 32 bit integer
             '0x32', '0x0',                 # key: "2"
             '0x16', '0x0', '0x0', '0x0',   # value: 22             
 # ...
]

除了一些格式开销之外,数组的每个值都相当浪费地使用 7 个字节进行编码:1 个字节用于指定数据类型,2 个字节用于包含索引的字符串(三个字节用于索引 >=10,四个字节用于指定数据类型)对于索引 >=100, ...) 和 4 个字节用于 32 位整数值。

这至少解释了为什么 BSON 数据比原始数组大得多。

我找到了两个库 GitHub - mongodb/bson-numpyGitHub - ajdavis/bson-numpy这可能会更好地在 BSON 中编码 numby 数组。但是,我没有尝试过它们,所以我不能说是否是这种情况,或者它们是否工作正常。

关于arrays - 为什么 BSON 序列化的 numpy 数组比原始数组大得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46460443/

相关文章:

c - 将 char 数组的指针传递给函数

python - pydantic 去除空白

python - 与 Python 相比,在 Matlab 中使用 FFT 的结果不同

php - 删除多维数组中具有相同键的重复值并将唯一值存储到另一个数组

javascript - 使用 JavaScript 从数组中的字符串中删除所有字母字符和前导零

c - 递归查找数组中相同元素的数量

python - 如何填充列表中的值并将其转换为数据帧?

python - 将十六进制字符串转换为 bytes 函数的正确形式

python - Pandas :与模式匹配的固定补丁滚动相关

Python 识别时间序列数据框中的美国假期