代码之家  ›  专栏  ›  技术社区  ›  Saturnix

Django分组并按权重聚合

  •  0
  • Saturnix  · 技术社区  · 7 年前

    我有一个这样的表,我使用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乘以权重,然后进行聚合。这将是低效和缓慢的(很多查询充其量,使用熊猫充其量)。

    可以用一个ORM查询还是一个SQL查询来实现?

    0 回复  |  直到 7 年前
        1
  •  1
  •   Tsang-Yi Shen    7 年前

    一种方法是 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)
        ))