【问题标题】:Django ORM get maximum value of a field and corresponding other column valuesDjango ORM获取字段的最大值和相应的其他列值
【发布时间】:2019-03-03 17:32:20
【问题描述】:

我有一个数据框:

`exp_no`   'time'   'price'

  1       0:00:00     20.0
  1       7 days      45.0
  1       15 days     100.0
  2       0:00:00     20.0
  2       7 days      45.0
  2       15 days     100.0

对应的Django模型:

class StData(models.Model):
      exp_no = models.ForeignKey(StIndex, on_delete=models.CASCADE)
      time = models.DateTimeField()
      price = models.DecimalField(max_digits=10, decimal_places=2)   

我想制作一个较小的表,其中包含 exp_no、max_time 和相应的价格:

 `exp_no`   'time'   'price'

  1       15 days     100.0
  2       15 days     100.0

在熊猫中,我会做df.groupby('exp_no')['time', 'price'].max().reset_index() 获取所需的表。

如果我这样做,在 Django ORM 注释中获得相同的结果(或查询集):

qs.values('exp_no').annotate(max_time=Max('time')).order_by()

它给了我exp_no和时间,但我也想得到相应的价格。我在 SO 中查看了这个答案:Django orm get latest for each group

但不确定我是如何得到价格的。将 Django 2.0 与 sqlite3 一起使用。

感谢您的帮助。

【问题讨论】:

    标签: python django pandas


    【解决方案1】:

    您的问题归结为获取具有最大time 列的记录的StData 对象(或值)。所以我们不需要聚合,而是获取关于time 列的最小或最大行。

    获取最大time的StData对象

    在'time' 下单时,只需获取last() 行,例如:

    stdata_max_time = qs<b>.order_by('time').last()</b>  # will return a StData

    或者:

    stdata_max_time = qs<b>.order_by('-time').first()</b>  # will return a StData

    如果time 是可空的(不在此处),您可以通过指定在订购时分别将它们作为第一个/最后一个元素放置来确保不会检索带有NULL 的行:

    from django.db.models import F
    
    # two alternatives
    stdata_max_time = qs.order_by(F('time', nulls_first=True)).last()
    stdata_max_time = qs.order_by(F('-time', nulls_last=True)).first()

    因此这是一个StData 对象,因此您可以从该对象中检索您想要的所有相关信息。由于它是一个StData 对象,它的行为也会像这样(因此您定义的额外属性、方法等也可以正常工作)。

    获取最大值time

    这完全相似,只是我们在查询中加入了.values(..) 调用:

    stdata_max_time = qs.order_by('time')<b>.values('exp_no', 'time', 'price')</b>.last()

    但除非有一些非常好的理由,否则我个人更喜欢获取 StData 对象,因为这意味着“包括电池”(你会得到你在 @987654339 中编写的所有逻辑@class 与该对象)。

    【讨论】:

    • 绝对优雅。也清除了我的概念。非常感谢。
    猜你喜欢
    • 2016-11-13
    • 2015-09-25
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2020-07-06
    • 2017-04-02
    相关资源
    最近更新 更多