【问题标题】:Django ORM to get average of data in 15 minutes time blockDjango ORM 在 15 分钟的时间块内获取数据的平均值
【发布时间】:2020-05-12 07:33:02
【问题描述】:

我每 30 秒抓取一次数据并将其存储在此模型中。

class Frequency(models.Model):
    """Store the frequency  scraped"""
    timestamp = models.DateTimeField()
    frequency = models.DecimalField(max_digits=5, decimal_places=2)

现在我被分配了一项任务,每天每 15 分钟我必须对结果进行平均并分组为 08:15-08:30、08:30-08:45 .... 23 :45-24:00。

我的想法是使用两个循环。外层会在一天中的几个小时内循环,内层会在 (00, 15, 30, 45) 中循环,然后更改今天的 datetime.now() 并对其进行过滤。

有没有更好的方法或者这样可以吗??

【问题讨论】:

    标签: django django-models django-orm


    【解决方案1】:

    通过对每个时间跨度进行独立过滤,您将每天进行 24*4 的数据库查询,这对于这样一个简单的操作来说就像很多。要在一个查询中实现它,您可以注释您的 frequencies 查询集并为每个对象设置 closest_quarter_of_hour。然后您可以使用aggregate 获取平均频率,并使用Django values 方法创建一个SQL group by 子句。

    from django.db.models import CharField, Case, When, Q, Value, Avg
    from django.db.models.functions import ExtractHour, ExtractMinute
    
    today = timezone.now().date()
    frequencies = Frequency.objects.filter(timestamp__date=today).annotate(
        hour=ExtractHour("timestamp"),
        minute=ExtractMinute("timestamp"),
    ).annotate(
        closest_quarter_of_hour=Case(
            When(minute__gte=0, minute__lt=15, then=Value('00-15')),
            When(minute__gte=15, minute__lt=30, then=Value('15-30')),
            When(minute__gte=30, minute__lt=45, then=Value('30-45')),
            When(minute__gte=45, then=Value('45-00')),
            output_field=CharField(),
        )
    ).aggregate(Avg("frequency")).values("hour", "closeset_quarter_of_hour")
    

    结果:一个 SQL 查询中每 15 分钟时间跨度的平均频率。

    【讨论】:

    • 这正是我所需要的,它确实是一个很棒的解决方案。但是在运行它时,它只给了我一个值..
    • 哦,也许是我的错误。请尝试.values("hour", "closeset_quarter_of_hour").annotate(average=Avg("frequency")) 而不是.aggregate(Avg("frequency")).values("hour", "closeset_quarter_of_hour")。如果它会工作,那么我会更新我的答案
    • 我再次运行了你的代码。它给出了值错误(无属性)。我将其删除并且代码成功运行。但是我得到的结果只有 4 个。我需要应该生成的 96 个结果。我的方法是我首先过滤掉一天的数据,然后在 range(24) 中创建一个外循环,在 (0, 15, 30, 45) 中创建一个内循环,并从以前的过滤结果中一次又一次地过滤并聚合 Avg .你的看起来效率更高,如果你能帮助我解决这个问题,我会非常感激。谢谢你刚刚向我展示了一种获得结果的新方法。
    猜你喜欢
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 2017-04-25
    • 2019-04-13
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多