2016-04-25 55 views
1

我想知道如果這是可能的更有效的方式。
我有PostgreSQL中數據集的結構是這樣的:聚合並計算在Django queryset中的arrayfield的中位數

Year, Sitename, Array (length = 4500) 

例如:

1982, DANC, array([2,3,4,5,6,7,...]) 
1982, ANCH, array([5,6,4,3,5,7,...]) 
1983, DANC, array([3,3,4,6,3,6,...]) 
1983, ANCH, array([8,8,5,4,3,2,...]) 

我想通過幾年要做的就是增加了陣列(跨行)

E.G., 
1982 1982 1982 
DANC ANCH TOT 
2  5  7 
3  6  9 
4  4  8 
5  3  8 
6  5  11 
7  7  14 
... ... ... 

我的Django模型看起來像這樣:

class Abundance(models.Model): 
    abundance_id = models.AutoField(primary_key=True) 
    site = models.ForeignKey('Site') 
    season = models.SmallIntegerField()   
    samples = ArrayField(models.DecimalField(blank=True, decimal_places=3, max_digits=30)) 

    def __unicode__(self): 
     return self.site 

我Views.py下面的代碼工作:

import numpy as np 
import bottleneck as bn 
... 


def testview(request): 

    s = ["ACUN","BRDM"] 
    quants = [] 
    medians = [] 
    for yr in range(1982,2015):        
     X = Abundance.objects.values_list('samples').filter(site__site_id__in = s).filter(season = yr) 
     h = np.matrix(np.array(X,dtype=float))  
     i = h.sum(axis=0)  
     m = bn.median(i)  
     up = np.percentile(i,95) 
     down = np.percentile(i,5) 
     qlist = [yr, round(down,3), round(up,3)] 
     mlist = [yr, round(m,3)] 
     quants.append(qlist) 
     medians.append(mlist) 

    return JsonResponse({'quants':quants, 'medians':medians}) 

然而,上面的代碼是非常緩慢的 - 吸引了許多網站時尤其如此。我曾嘗試玩.aggregate(),但我還沒有找到一個好的解決方案。

在此先感謝

回答

0

你或許可以使用一些.aggregate()上有推負荷下降到Postgres的,但我認爲的更大的問題與速度一個這裏是小數場。這是最高的精度,但它也是Python進出的更昂貴的類型之一。

這就是說,我不確定是否有一種快速的方法可以從數據庫調用中獲得百分位數,但是可以通過Django ORM輕鬆地將數據和中位數推送到數據庫。對於其他人(百分比等),你也可以推低他們,但你會鑽研django的自定義聚合(https://docs.djangoproject.com/en/1.9/ref/models/expressions/#creating-your-own-aggregate-functions),如果你要走這麼遠,可能值得檢查一些東西aldjemy(https://github.com/Deepwalker/aldjemy/)並將整個查詢轉換爲SQLAlchemy,以便最大限度地控制它。