2011-06-01 29 views
0

說,我有一個模型,它定義了一個汽車,它的一個領域是'製造商'。例如:獲取餅圖數據

class Car(models.Model): 
    manufacturer = models.CharField(max_length=50) 
    color = models.CharField(max_length=50) 
    licence_plate = models.CharField(max_length=50) 
    . 
    . 
    . 

要繪製一個餅圖來顯示各個製造商的總數(使用matplotlib),我需要兩個列表。一個包含製造商總數,另一個包含相應的製造商名稱。所以我想結束這樣的事情。

[516, 122, 131, 125, ... 
['Ford','BMW','Mazda','Honda', ... 

順便說一下,我不知道製造商的名稱事先。

還有一件事,我只想顯示前5名製造商。所有其他人應該被集中在一個名爲「其他」的製造商。

我如何獲得這些列表?

+0

最初存儲的數據如何? – Tim 2011-06-01 07:25:09

+0

你還沒有說過你應該從哪裏得到總數的數字。那是否存儲在Car的另一個屬性中?或者你數一下汽車的數量? – 2011-06-01 07:26:47

+0

@Tim我已經解決了這個問題。 – gerty 2011-06-01 07:28:29

回答

0

不知道這是完全正確的,但你需要像:

from django.db.models import Count, Sum 

num_taken = 5 # modify this if you want more/less than 5 
query = Car.objects.values('manufacturer').annotate(num_cars=Count('manufacturer')).order_by('-num_cars') 
top_cars = query[:num_taken] 
others = query[num_taken:].aggregate(total=Sum('num_cars'))['total'] 
car_nums = [entry['num_cars'] for entry in top_cars] + [others] 
car_manufactureres = [entry['manufacturerer'] for entry in top_cars] + ['Others'] 
+0

謝謝,這非常接近。但是,我不希望忽略未進入前五名的製造商的總數。我想將所有低於前五名的選手放在另一個名爲「其他」的組中。 – gerty 2011-06-01 07:46:01

+0

@gerty查看編輯 – 2011-06-01 07:48:15

0

這裏是一個純Python(你處理Django的東西)的解決方案。我自己做了一些汽車對象來測試代碼。

from random import choice 
from collections import defaultdict 
from operator import itemgetter 

manufacturers = ["Ford", "BMW", "Mazda", "Honda", "Volvo", "Saab", "Toyota"] 
cars = [type("Car", (object,), {"manufacturer": choice(manufacturers)}) 
    for x in range(1000)] 

count = defaultdict(int) 
for car in cars: 
    count[car.manufacturer] += 1 

top = sorted(count.items(), key=itemgetter(1), reverse=True) 
other = sum(x[1] for x in top[5:]) 
list1 = [x[0] for x in top[:5]] + ["other"] 
list2 = [x[1] for x in top[:5]] + [other] 

print list1 
print list2 
+0

這很有幫助。 – gerty 2011-06-01 13:01:11