Reputation: 161
I have around 6000 values. Each value has a field called total
. I need to generate (I guess this part should be at the views.py
) a set of the rounded average for every 3 elements (groups).
Example: 1 3 100 4 5 8 10 1 20 ...
Desired set: 35 6 10 ...
My models.py looks like:
class resume(models.Model):
total = models.DecimalField(max_digits=9, decimal_places=2,default=0)
I was thinking on adding something that has to do with resume.objects.all().aggregate(Avg('total'))
at the views.py
(when rendering). Some solutions I have seen use SQL. Any idea on how to do this from django?
Upvotes: 0
Views: 757
Reputation: 2706
Fixed:
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)]
Now it's even a little less clunky thanks to the aggregate function. The first line pulls out the total values from all of the resumes. Next there's a string comprehension for i in the first third of all_res that sums the 3 digits from i*3 to (i*3)+3. The first iteration of i in the list comprehension would go like this (let's assume that all_res starts [5, 4, 6, .....]):
sum(all_res[(0*3):((0*3)+3)])/3
sum(all_res[0:3])/3
sum([5,4,6])/3
15/3
# 5
Edit: Also, I figure it's not a huge deal, but if your DB doesn't have n records where n%3 = 0 (I figure 6k was a rounded off figure), and you REALLY need every number to be right, then you could always divide by the len(i*3:i*3+3) instead of 3 since if the upper bound on a slice overruns it just returns the list until the end.
Upvotes: 1
Reputation: 369124
You may need to do it manually as follow:
# 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)]
Upvotes: 2