Django分组依据并进行权重汇总

时间:2019-08-10 00:13:21

标签: python django orm django-orm

我有一个这样的表,可以使用Django ORM与之交互。

date                car_crashes         city
01.01               1                   Washington
01.02               4                   Washington
01.03               0                   Washington
01.04               2                   Washington
01.05               0                   Washington
01.06               3                   Washington
01.07               4                   Washington
01.08               1                   Washington
01.01               0                   Detroit
01.02               2                   Detroit
01.03               4                   Detroit
01.04               2                   Detroit
01.05               0                   Detroit
01.06               3                   Detroit
01.07               1                   Detroit

我想知道整个国家每天发生多少起车祸,我可以这样做:

Model.values("date") \
.annotate(car_crashes=Sum('car_crashes')) \
.values("date", "car_crashes")

date  car_crashes
1.01            1
1.02            6
1.03            4
1.04            4
1.05            0
1.06            6
1.07            5
1.08            1

现在,让我们假设我有一个像这样的数组:

weights = [
    {
        "city": "Washington",
        "weight": 1,
    },
    {
        "city": "Detroit",
        "weight": 2,
    }
]

这意味着底特律的车祸应该与华盛顿相乘之前应乘以2。

我的解决方案是分别汇总所有不同的权重,再用Pandas或SQL乘以权重,然后进行汇总。这将是低效且缓慢的(充其量是很多查询,最糟糕的是使用Pandas)。

是否可以通过单个ORM查询或SQL查询来实现?

1 个答案:

答案 0 :(得分:1)

一种方法是使用Conditional Expressions确定查询中的权重值,这意味着您可以首先构造Case表达式:

from django.db.models import IntegerField

when_list = [When(city=w['city'], then=w['weight']) for w in weights]
case_params = {'default': 1, 'output_field': IntegerField()}

Model.objects.values('date') \
    .annotate(
        weighted_car_crashes=Sum(
            F('car_crashes') * Case(*when_list, **case_params)
    ))