Django 按权重分组并聚合
Django group by and aggregate with weights
我有一个这样的 table,我使用 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 查询来实现?
一种方法是使用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)
))
我有一个这样的 table,我使用 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 查询来实现?
一种方法是使用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)
))