2009-06-03 16 views
8

開発バージョンのDjangoには、Avg、Count、Max、Min、StdDev、Sum、およびVariance(link text)などの集計関数があります。メディアンがリストにない理由はありますか?Djangoの 'Median'集計関数がありませんか?

実現するのは簡単だと思われます。何か不足していますか?舞台裏で集計関数はどれくらいかかりますか?

答えて

7

の理由は、おそらく中央値を計算するためにすべての数値をトラッキングする必要があると考えられます。平均、カウント、最大、最小、StDev、合計、および分散は、すべて一定のストレージの必要性で計算できます。つまり、一度、あなたがもう一度それを必要としない数字を "記録"します。

FWIWでは、最小、最大、カウント、<n> =平均、<n^2> =値の2乗の平均値を追跡する必要があります。

2

中央値は標準SQLに含まれていない可能性があります。

また、ソートが必要なため、計算が非常に高価になります。

+0

線形、非ソート、アルゴリズムがあります。http://valis.cs.uiuc.edu/~sariel/research/CG/applets/linear_prog/median.html –

+0

間違ったアルゴリズムは、私は中央値の中央値を意味:http://en.wikipedia.org/wiki/Selection_algorithm#Linear_general_selection_algorithm_-_.22Median_of_Medians_algorithm.22 –

+0

@Todd Gardner:最初のリンクは「パーティションベースの一般選択」で、O(nlogn)は線形ではありません。サイトは間違っています。そのコメントを削除するのは良いことですが、メディアンの中央値をコメントのままにしておきます。 –

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))] 

などのハード他の応答の一部を示すように見えるようではなかった。それをクエリセットとあなたのための中央値を見つけたい列の名前を渡します。重要なのは、データベースのソートにすべての作業を行わせることです。そのため、すでに索引付けされている列がある場合は、これは超安価な操作です。

(2016年1月28日の更新) あなたはアイテムの数が偶数のための中央値の定義についてより厳密になりたい場合は、これは2つの中間値の値を一緒に平均化されます。

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) 
+0

要素の数が偶数の場合、この実装には小さな不正確さがあります。 https://en.wikipedia.org/wiki/Medianからの引用:「偶数個の観測値がある場合、中間値は1つもないため、中央値は通常は2つの中間値の平均値として定義されます" 一度values_listが取得されると、そのような関数のためにpythonの 'median'関数を使用するのが最適です(このスレッドを参照してください):http://stackoverflow.com/questions/24101524/finding-median-of-list -in-python) –

+0

@o_cこれは有効な点ですが、私はデータセット全体に対してpythonのメディアン関数を使用することをお勧めしません。これは高価な操作です。カウントが偶数であれば小さな変化。私は一緒に何かを投げることができるかどうかを見ます。 –

関連する問題