Django ORM获取字段的最大值和相应的其他列值

时间:2018-09-27 18:29:24

标签: python django pandas

我有一个DataFrame:

`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配合使用。

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您的问题归结为获得StData列最大的记录的time对象(或值)。因此,我们不需要聚合,而是获得相对于time列的最小或最大行。

获得最大StData的{​​{1}}对象

time上订购时,您只能获得last()行,例如:

'time'

或者:

stdata_max_time = qs.order_by('time').last()  # will return a StData

如果stdata_max_time = qs.order_by('-time').first() # will return a StData可为空(此处不是),可以通过指定在排序时分别将其放置为第一个/最后一个元素来确保不使用time检索行: / p>

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').values('exp_no', 'time', 'price').last()对象,因为这意味着“包含电池”(您会获得在StData类与该对象)。