python 连接数据库导数_python – 使用MongoDB聚合框架计算一阶导数
我们可以使用MongoDB 3.2或更高版本中的聚合框架来实现,因为我们真正需要的是一种跟踪数组中当前和上一个元素的索引的方法,幸运的是从MongoDB 3.2开始,我们可以使用
$unwind运算符来解构我们的数组,并通过指定一个文档作为操作数,而不是以$为前缀的传统“路径”,包括数组中每个元素的索引.
从那里我们有两个选择.第一个是MongoDB 3.2,第二个是即将发布的MongoDB(在撰写本文时).
下一步在管道中,我们需要$group我们的文档,并使用$push累加器运算符返回一个如下所示的子文档数组:
{
"_id" : ObjectId("57c11ddbe860bd0b5df6bc64"),
"time_series" : [
{ "value" : 10, "index" : NumberLong(0) },
{ "value" : 20, "index" : NumberLong(1) },
{ "value" : 40, "index" : NumberLong(2) },
{ "value" : 70, "index" : NumberLong(3) },
{ "value" : 110, "index" : NumberLong(4) }
]
}
终于到了$project阶段.在这个阶段,我们需要使用$map运算符将一系列表达式应用于$group阶段新计算的数组中的每个元素.
这是在$map里面发生了什么(请参阅$map作为for循环)在表达式中:
对于每个子文档,我们使用$let变量运算符将值字段分配给变量.然后,我们从数组中下一个元素的“值”字段的值中减去它的值.
由于数组中的下一个元素是当前索引的元素加1,所以我们需要的是$arrayElemAt运算符的帮助和当前元素索引的简单$add和1.
$subtract表达式返回一个负值,因此我们需要使用$multiply运算符将值乘以-1.
我们还需要$filter所得到的数组,因为最后一个元素是None或null.原因是当当前元素是最后一个元素时,$subtract返回None,因为下一个元素的索引等于数组的大小.
db.collection.aggregate(
[
{ "$unwind": {
"path": "$time_series",
"includeArrayIndex": "index"
}},
{ "$group": {
"_id": "$_id",
"time_series": {
"$push": {
"value": "$time_series",
"index": "$index"
}
}
}},
{ "$project": {
"time_series": {
"$filter": {
"input": {
"$map": {
"input": "$time_series",
"as": "el",
"in": {
"$multiply": [
{ "$subtract": [
"$$el.value",
{ "$let": {
"vars": {
"nextElement": {
"$arrayElemAt": [
"$time_series",
{ "$add": [
"$$el.index",
1
]}
]}
},
"in": "$$nextElement.value"
}
}
]},
-1
]
}
}
},
"as": "item",
"cond": { "$gte": [ "$$item", 0 ] }
}
}
}}
]
)
在即将推出的版本中将提供另一种选择.
首先在$group阶段,我们返回两个不同的数组.一个用于元素,另一个用于索引,然后$zip如下所示的两个数组:here.从他们,我们只需使用整数索引访问每个元素,而不是将其值分配给带有$let的变量.
db.collection.aggregate(
[
{ "$unwind": {
"path": "$time_series",
"includeArrayIndex": "index"
}},
{ "$group": {
"_id": "$_id",
"values": { "$push": "$time_series" },
"indexes": { "$push": "$index" }
}},
{ "$project": {
"time_series": {
"$filter": {
"input": {
"$map": {
"input": {
"$zip": {
"inputs": [
"$values",
"$indexes"
]
}
},
"as": "el",
"in": {
"$multiply": [
{ "$subtract": [
{ "$arrayElemAt": [
"$$el",
0
]},
{ "$arrayElemAt": [
"$values",
{ "$add": [
{ "$arrayElemAt": [
"$$el",
1
]},
1
]}
]}
]},
-1
]
}
}
},
"as": "item",
"cond": { "$gte": [ "$$item", 0 ] }
}
}
}}
]
)
请注意,我们也可以在$project stage的早期使用$reverse来反转阵列,如图here所示,以避免使用$multiply.
这两个查询都产生如下:
{
"_id" : ObjectId("57c11ddbe860bd0b5df6bc64"),
"time_series" : [ 10, 20, 30, 40 ]
}
我认为效率较低的另一个选项是使用map_reduce方法对我们的收集执行地图/缩小操作.
>>> import pymongo
>>> from bson.code import Code
>>> client = pymongo.MongoClient()
>>> db = client.test
>>> collection = db.collection
>>> mapper = Code("""
... function() {
... var derivatives = [];
... for (var index=1; index
... derivatives.push(this.time_series[index] - this.time_series[index-1]);
... }
... emit(this._id, derivatives);
... }
... """)
>>> reducer = Code("""
... function(key, value) {}
... """)
>>> for res in collection.map_reduce(mapper, reducer, out={'inline': 1})['results']:
... print(res) # or do something with the document.
...
{'value': [10.0, 20.0, 30.0, 40.0], '_id': ObjectId('57c11ddbe860bd0b5df6bc64')}
您还可以检索所有文档,并使用numpy.diff返回导数,如下所示:
import numpy as np
for document in collection.find({}, {'time_series': 1}):
result = np.diff(document['time_series'])
现在怎么样一点基准:
机:
OS: Ubuntu 16.04
Memory: 15.6 GiB
Processor: Intel® Xeon(R) CPU E3-1231 v3 @ 3.40GHz × 8
在我的机器上按照这个顺序运行的三个查询分别给出以下结果:
基准测试结果与500个文件:
MongoDB 3.2
100 loops, best of 3: 2.32 ms per loop
MongoDB 3.3.11
1000 loops, best of 3: 1.72 ms per loop
MapReduce的
100 loops, best of 3: 15.7 ms per loop
100 loops, best of 3: 3.61 ms per loop
结论
即使解决方案不明显,使用聚合也是预期的最佳选择.
由于JavaScript评估,mapReduce解决方案是微不足道的,但效率很低.
*您可以通过安装MongoDB的当前开发版本(作为本写作时间)来测试第二个查询.
python 连接数据库导数_python – 使用MongoDB聚合框架计算一阶导数相关推荐
- mongodb 聚合框架_如何使用MongoDB的聚合框架处理高级数据处理
mongodb 聚合框架 MongoDB has come a long way. Even though there are many NoSQL databases out there, Mong ...
- Mongodb聚合框架Aggregate
一 概念 1.简介 mongo aggregation是mongo的一个轻量级的map-reduce框架,可以实现一些count,sum,group by的聚合. 使用聚合框架可以 ...
- python twisted教程_Python下的twisted框架入门指引
什么是twisted? twisted是一个用python语言写的事件驱动的网络框架,他支持很多种协议,包括UDP,TCP,TLS和其他应用层协议,比如HTTP,SMTP,NNTM,IRC,XMPP/ ...
- python spider 安装_Python爬虫(11):Scrapy框架的安装和基本使用
大家好,本篇文章我们来看一下强大的Python爬虫框架Scrapy.Scrapy是一个使用简单,功能强大的异步爬虫框架,我们先来看看他的安装. Scrapy的安装 Scrapy的安装是很麻烦的,对于一 ...
- mongodb python 存文件_Python保存MongoDB上的文件到本地的方法介绍
本文实例讲述了Python保存MongoDB上的文件到本地的方法.分享给大家供大家参考,具体如下: MongoDB上的文档通过GridFS来操作,Python也可以通过pymongo连接MongoDB ...
- python连接数据库步骤_Python连接mysql数据库
Python中连接MySQL的库主要有三个,Python-MySQL,PyMySQL和SQLAlchemy,其中Python-MySQL已经停止更新,且只支持Python2,目前使用最广泛的是PyMy ...
- python 电脑状态_Python实现简单状态框架的方法 -电脑资料
作者:chongq 字体:[增加 减小] 类型:转载 这篇文章主要介绍了Python实现简单状态框架的方法,涉及Python状态框架的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述 ...
- python label 边框_Python Tkinter LabelFrame标签框架
LabelFrame小部件用于在其子小部件周围绘制边框.我们还可以显示LabelFrame小部件的标题.它就像一个容器,可以用来分组相互关联的小部件的数量,如Radiobuttons. 此小部件是Fr ...
- python技术介绍_Python编程语言基础技术框架()之函数介绍
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
最新文章
- LeetCode简单题之构造矩形
- 浏览器是怎样工作的(一):基础知识
- 整活插件 炉石传说_炉石传说:一顿操作猛如虎,定睛一看原地杵,会长整活被死人抬走...
- java filehelper_Spring 发送邮件 使用File指定附件
- cURL error 60: SSL certificate problem: unable to get local issuer certificate 解决思路
- ObjectContext.Refresh
- 外部依赖项很多未定义标识符_从日本编程书籍《我的第一本编程书》中译版看中文例程如何扬长避短——标识符(一)
- mysql中国菜刀连接_中国菜刀使用方法以及小技巧
- python怎么读取excel-python怎么读取excel表格
- T-SQL: 读取磁盘文件
- 词云python灿烈,Python jieba分词、词云、文件读取、函数调用、匿名函数
- SAP FI 系列 (022) - 货币和汇率的配置
- N1烧USB供电跳线修复方法
- oracle+bmp转为txt,Bmp2Txt下载-图像转换成文字(Bmp2Txt )下载1.0-西西软件下载
- html文本框颜色填充颜色设置,Excel2007中设置文本框填充方案 文本框填充颜色
- Excel如何对多分隔符号数据进行分列
- 入门篇——解析Python机器学习中三类无监督学习算法和两个应用实例
- 【百度地图API】如何利用自己的数据制作社交地图?只显示可视区域内的标注...
- 基于 arduino 的两轮自行车
- 人脑的算力真的很弱吗