【问题标题】:Django group by and aggregate with weightsDjango 按权重分组并聚合
【发布时间】:2019-12-17 16:28:10
【问题描述】:

我有一个这样的表,我使用 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 查询来完成?

【问题讨论】:

    标签: python django orm django-orm


    【解决方案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)
        ))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      相关资源
      最近更新 更多