Django按组取3的模型字段平均值
我有大约6000个值。每个值都有一个叫做 total
的字段。我需要生成一个每3个元素的平均值(取整)的集合(分组)。
举个例子: 1 3 100 4 5 8 10 1 20 ...
想要的结果集: 35 6 10 ...
我的 models.py
文件看起来是这样的:
class resume(models.Model):
total = models.DecimalField(max_digits=9, decimal_places=2,default=0)
我在想要在 views.py
中添加一些与 resume.objects.all().aggregate(Avg('total'))
相关的内容(在渲染的时候)。我看到的一些解决方案使用了SQL。有没有什么办法可以在django中做到这一点?
2 个回答
1
修复了:
from django.db.models import Avg
all_res = Resume.objects.all()
answer = [ all_res[(i*3):((i*3)+3)].aggregate(Avg('total') for i in range(all_res.count()/3)]
现在因为用了聚合函数,代码变得更简洁了。第一行从所有的简历中提取出总值。接下来,有个字符串理解的过程,它会对所有简历的前三分之一进行处理,计算从 i*3 到 (i*3)+3 这三个数字的和。假设 all_res 的开头是 [5, 4, 6, .....], 那么在列表理解的第一次循环中,i 的值会这样变化:
sum(all_res[(0*3):((0*3)+3)])/3
sum(all_res[0:3])/3
sum([5,4,6])/3
15/3
# 5
补充说明:我觉得这不是大问题,但如果你的数据库里没有 n 条记录,并且 n%3 = 0(我猜 6000 是个大概的数字),而你又非常需要每个数字都准确的话,那么你可以用 len(i*3:i*3+3) 来代替 3 来进行计算,因为如果切片的上限超出了范围,它会返回到列表的末尾。
2
你可能需要手动按照下面的步骤来操作:
# http://docs.python.org/2/library/itertools.html
def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
def avg(xs):
xs = [x for x in xs if x is not None]
return sum(xs) / len(xs)
# Retrieve all `total` values as a flat list-like ValueListQuerySet.
values = resume.objects.all().values_list('total', flat=True)
avgs = [avg(xs) for xs in grouper(values, 3)]