2009-06-03 53 views

回答

7

那麼,原因可能是你需要跟蹤所有的數字來計算中位數。 Avg,Count,Max,Min,StDev,Sum和Variance都可以用恆定的存儲需求來計算。也就是說,一旦你「記錄」了一個數字,你就再也不需要它了。

FWIW,您需要跟蹤的變量有:最小值,最大值,計數,<n> = avg,<n^2> =值的平方的平均值。

2

很有可能是中位數不是標準SQL的一部分。

此外,它需要排序,使其計算相當昂貴。

+0

有線性的,非排序,算法:http://valis.cs.uiuc.edu/~sariel/research/CG/applets/linear_prog/median.html – 2009-06-03 01:59:27

+0

錯算法,我的意思是中位數的中值:http://en.wikipedia.org/wiki/Selection_algorithm#Linear_general_selection_algorithm_-_.22Median_of_Medians_algorithm.22 – 2009-06-03 02:03:43

2

我不知道你使用的是哪個db後端,但是如果你的數據庫支持另一個聚合,或者你可以找到一個聰明的方法,你可以很容易地通過Aggregate來訪問它。

1

FWIW,您可以擴展PostgreSQL 8.4及更高版本以獲得中值聚合函數these code snippets

其他代碼段(這對於老版本的PostgreSQL的工作)是shown here。請務必閱讀此資源的評論。

15

這是您的遺漏功能。它傳遞一個查詢集,並要找到中間的列的名稱:

def median_value(queryset, term): 
    count = queryset.count() 
    return queryset.values_list(term, flat=True).order_by(term)[int(round(count/2))] 

這是不是很難,因爲其他一些答覆似乎表明。重要的是讓db排序完成所有的工作,所以如果你的列已經被索引,這是一個非常便宜的操作。

(更新2016年1月28日) 如果你想更加嚴格有關的偶數項的中位數的定義,這將平均在一起的兩個中間值的值。

def median_value(queryset, term): 
    count = queryset.count() 
    values = queryset.values_list(term, flat=True).order_by(term) 
    if count % 2 == 1: 
     return values[int(round(count/2))] 
    else: 
     return sum(values[count/2-1:count/2+1])/Decimal(2.0)