2009-06-03 76 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)