Как выполнить выборку временных рядов для каждой n-й строки в Django? - PullRequest
2 голосов
/ 03 февраля 2020

Цель

Я пытаюсь сократить объем данных, отправляемых на внешний интерфейс приложения, путем выборки временных рядов. Первоначально, просто взяв каждую n-ю строку, потому что я также хочу оптимизировать скорость.

Макет

Я использую Django 2.1.5, с PostgreSQL бэкэнд. Таблица временных рядов заполняется данными измерений каждые 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)

Смежные вопросы

Несколько ресурсов нашли подходящее решение здесь Как отфильтровать / уменьшить QuerySet для каждой n-й строки? и { ссылка }, основанный на аннотировании с помощью буквы «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 |
+----+--------+------+-------+

Если теперь кто-то пытается отфильтровать для датчика 'A' с% 2, список выглядит только как

|  2 | A      |  534 | 10:15 |

, а для 'B'

|  4 | B      |   87 | 10:25 |
|  6 | B      |  982 | 10:45 |
|  8 | B      |  400 | 10:50 |

Оконная функция

Я думал об использовании Window функции Django

 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.

И это также упоминается в документах

По умолчанию False. Стандарт SQL запрещает ссылаться на оконные функции в предложении WHERE, а Django вызывает исключение при создании QuerySet, который будет делать это

и вытекает из логической обработки SQL , который сначала проходит через WHERE перед SELECT, поэтому нет способа выполнить этот запрос.

Вопрос

Что такое достаточно быстрый способ выборка этого временного ряда, чтобы уменьшить набор данных? В идеале я бы пропустил фильтр по времени и датчику

.filter(sensor=thisSensor).filter(time__range=(rangeStart, rangeEnd))

и показал бы подвыборку, скажем, 200 записей.

1 Ответ

1 голос
/ 03 февраля 2020

Один из способов сделать это, поскольку ваши данные противоречивы, вы можете либо квантовать данные перед отправкой, либо выбрать нужные точки, а затем с помощью регрессии предсказать недостающие точки в js в браузере

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...