目标
我试图通过对时间序列进行二次采样来减少发送到应用程序前端的数据。最初只取第 n 行,因为我也想优化速度。
布局
我使用的是带有 PostgreSQL 后端的 Django 2.1.5。
时间序列表中每 1-15 分钟就会填充来自各种传感器的测量数据。
models.py
class Measurement(models.Model):
sensor = models.ForeignKey(Category,on_delete=models.PROTECT,related_name='measurements')
datapoint = models.DecimalField(max_digits=8, decimal_places=4)
time = models.DateTimeField(auto_now_add=True)
相关问题
一些资源在这里找到了一个紧密的解决方案
How to filter/reduce a QuerySet to every nth row?
和
https://stackoverflow.com/a/56487889/11225898
它基于使用“F”进行注释,如下所示:
views.py
Measurement.objects.annotate(idmod2=F('id') % 2).filter(idmod2=0)
这在一定程度上确实有效,但是由于测量是由大约 5-25 个不同的传感器进行的,并且每大约 1-15 分钟进行一次,因此 id 字段无法始终如一地跟踪。只是为了形象化一个简化的例子:
+----+--------+------+-------+
| id | sensor | data | time |
+----+--------+------+-------+
| 1 | A | 432 | 10:00 |
| 2 | A | 534 | 10:15 |
| 3 | B | 2342 | 10:20 |
| 4 | B | 87 | 10:25 |
| 5 | B | 2 | 10:30 |
| 6 | B | 982 | 10:45 |
| 7 | A | 23 | 10:45 |
| 8 | B | 400 | 10:50 |
+----+--------+------+-------+
如果现在尝试使用 %2 过滤传感器“A”,则列表看起来像
| 2 | A | 534 | 10:15 |
而对于'B'
| 4 | B | 87 | 10:25 |
| 6 | B | 982 | 10:45 |
| 8 | B | 400 | 10:50 |
窗函数
我想到了使用 Window姜戈的功能
Measurement.objects.annotate(place=Window(expression=RowNumber(),partition_by=[F('sensor')], order_by=F('time').desc()))
这使
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.
而这在docs中也有提到
Defaults to False. The SQL standard disallows referencing window functions in the WHERE clause and Django raises an exception when constructing a QuerySet that would do that
并且源于 SQL logical query processing ,它在 SELECT 之前首先经过 WHERE,因此无法执行此查询。
问题
对该时间序列进行子采样以减少数据集的合理快速方法是什么?理想情况下,我会通过时间和传感器的过滤器
.filter(sensor=thisSensor).filter(time__range=(rangeStart, rangeEnd))
并显示一个子样本,比如 200 条记录。
最佳答案
您可以做的一种方法是,由于您的数据不一致,您可以在发送之前量化数据,也可以选择您想要的点,然后通过回归预测浏览器中js中的缺失点
关于python - 如何将时间序列子采样到 Django 中的每一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60042291/