You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PyMongo的bson包将numpy数组写入.bson文件?

解决BSON编码numpy.ndarray的问题

PyMongo的bson模块无法直接编码numpy数组,因为BSON规范原生不支持numpy.ndarray类型,必须先将数组转换为BSON可识别的兼容类型。以下是具体解决方法和IO指引:

核心解决思路

BSON仅支持基础数据类型(如列表、字节串、数字、字符串等),需将numpy数组转换成这些格式,推荐两种常用方案:

方案1:转换为Python列表(代码简洁,适合中小数据量)

直接使用numpy数组的.tolist()方法转换,读取时再转回numpy数组:

import bson
import numpy as np

# 示例字典(替换为你的my_dict)
my_dict = {'0': np.random.rand(10, 400000), '1': np.random.rand(10, 400000)}

# 转换数组为列表
converted_dict = {k: v.tolist() for k, v in my_dict.items()}

# 写入BSON文件
with open('file_name.bson', 'wb') as f:
    f.write(bson.encode(converted_dict))

读取还原代码:

with open('file_name.bson', 'rb') as f:
    data = bson.decode(f.read())

# 转回numpy数组
restored_dict = {k: np.array(v) for k, v in data.items()}

方案2:转换为字节串(高效省空间,适合大数据量)

用numpy的.tobytes()将数组转为字节串,同时保存数组的形状和数据类型,确保还原时能准确恢复:

import bson
import numpy as np

my_dict = {'0': np.random.rand(10, 400000), '1': np.random.rand(10, 400000)}

# 封装数组的字节数据、形状、类型
converted_dict = {}
for k, arr in my_dict.items():
    converted_dict[k] = {
        'data': arr.tobytes(),
        'shape': arr.shape,
        'dtype': str(arr.dtype)
    }

# 写入BSON文件
with open('file_name.bson', 'wb') as f:
    f.write(bson.encode(converted_dict))

读取还原代码:

with open('file_name.bson', 'rb') as f:
    data = bson.decode(f.read())

restored_dict = {}
for k, info in data.items():
    restored_arr = np.frombuffer(info['data'], dtype=info['dtype']).reshape(info['shape'])
    restored_dict[k] = restored_arr

BSON文件IO关键注意事项

  • 类型兼容性:严格遵循BSON支持的原生类型(None、bool、int、float、str、bytes、list、dict、datetime等),非原生类型必须提前转换。
  • 数据大小限制:单条BSON文档最大16MB(你已排除此问题,但后续数据扩容时需注意,超大文件可考虑拆分文档或使用GridFS)。
  • 元数据一致性:转换时记录的数组形状、数据类型等元数据,必须和还原时完全匹配,否则会出现数据变形或类型错误。
  • 效率选择:转列表的方式代码简单,但大数据场景下内存占用高;转字节串更节省存储空间,读写速度更快,适合大数组场景。

内容的提问来源于stack exchange,提问作者seeker_after_truth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:10:47