如何用Python(PyMongo)在MongoDB存储矩阵并双关键字查询数值
使用PyMongo实现矩阵数据的MongoDB存储与查询
核心思路
直接存储原始矩阵会导致查询效率低下,最优方案是将每个(frequency, input_level)对应的数值拆分为独立文档,这样可以直接通过两个关键字精准查询对应值,无需遍历整个矩阵。每个文档的结构为:
{"frequency": <频率值>, "input_level": <输入等级>, "value": <对应矩阵数值>}
实现步骤
1. 安装依赖库
确保安装pymongo和numpy:
pip install pymongo numpy
2. 连接MongoDB
初始化MongoDB客户端,指定数据库和集合:
import pymongo import numpy as np # 连接本地MongoDB(如果是远程实例,替换为对应URI) client = pymongo.MongoClient("mongodb://localhost:27017/") # 创建/选择数据库 db = client["matrix_database"] # 创建/选择集合 collection = db["matrix_entries"]
3. 数据预处理与批量插入
遍历所有frequency和input_level的组合,生成可插入的文档列表,然后批量插入:
# 定义原始数据 frequency = np.array([5.00E+07, 5.01E+7, 5.02E+07, 5.03E+07, 5.04E+07, 5.05E+07, 5.06E+07, 5.07E+07, 5.08E+07, 5.09E+07, 6.00E+07]) input_level = np.array([1,2,3,4,5,6,7,8,9,10]) entry = np.matrix([ [8.53, 4.10, 5.79, 3.77, 8.95, 9.83, 6.15, 5.37, 2.61, 2.67, 8.01], [1.91, 7.63, 3.92, 7.45, 8.88, 6.18, 7.28, 9.33, 7.08, 8.78, 6.55], [7.96, 8.10, 5.27, 2.58, 5.47, 2.63, 2.30, 6.24, 6.94, 5.68, 9.94], [2.95, 2.52, 5.62, 3.54, 4.43, 9.17, 9.56, 6.66, 5.25, 8.57, 7.52], [5.48, 2.03, 8.26, 4.16, 1.55, 6.77, 1.96, 3.73, 6.26, 9.77, 8.67], [4.99, 9.45, 8.97, 9.87, 3.11, 1.94, 5.20, 1.47, 1.94, 8.08, 5.08], [9.49, 4.28, 6.82, 2.72, 7.94, 8.90, 4.97, 8.61, 1.37, 5.91, 7.41], [2.32, 4.75, 3.72, 3.03, 4.58, 3.87, 8.89, 3.14, 6.31, 5.78, 3.50], [1.82, 2.47, 7.78, 1.67, 4.19, 8.68, 7.10, 1.89, 3.51, 2.13, 7.77], [8.52, 6.06, 1.38, 2.96, 9.38, 8.43, 4.00, 2.55, 6.83, 3.57, 2.90]]) # 生成文档列表 documents = [] for idx_level, level in enumerate(input_level): for idx_freq, freq in enumerate(frequency): # 从矩阵中取出对应数值(entry是矩阵,需用.item()获取单个值) value = entry[idx_level, idx_freq].item() documents.append({ "frequency": float(freq), "input_level": int(level), "value": value }) # 批量插入数据(先清空集合避免重复插入,可选) collection.delete_many({}) collection.insert_many(documents)
4. 创建复合索引优化查询
为frequency和input_level创建复合索引,大幅提升查询速度:
# 创建复合唯一索引(确保同一(frequency, input_level)组合不重复) collection.create_index([("frequency", pymongo.ASCENDING), ("input_level", pymongo.ASCENDING)], unique=True)
5. 执行查询
通过指定两个关键字查询对应数值:
def get_value(freq, level): result = collection.find_one({ "frequency": freq, "input_level": level }) return result["value"] if result else None # 测试示例查询 print(get_value(5.05e7, 6)) # 输出:1.94
关键说明
- 拆分文档的优势:MongoDB擅长处理文档型数据,单文档查询的性能远高于遍历矩阵查询。
- 数值精度:MongoDB会将
frequency存储为double类型,查询时确保输入的数值类型与存储一致(如用5.05e7而非字符串)。 - 唯一索引:避免重复插入相同的(frequency, input_level)组合,保证数据唯一性。
内容的提问来源于stack exchange,提问作者MRR
相关产品推荐
相关产品推荐

