Отсутствует «срединная» агрегатная функция в Джанго? - PullRequest
10 голосов
/ 03 июня 2009

Версия Django для разработчиков имеет агрегатные функции, такие как Avg, Count, Max, Min, StdDev, Sum и Variance ( текст ссылки ). Есть ли причина, по которой Медиана отсутствует в списке?

Реализация одного кажется легкой. Я что-то пропустил? Сколько агрегатных функций делают за кулисами?

Ответы [ 6 ]

20 голосов
/ 29 февраля 2012

Вот ваша недостающая функция. Передайте ему набор запросов и имя столбца, для которого вы хотите найти медиану:

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

Это было не так сложно, как показывают некоторые другие ответы. Важно, чтобы сортировка БД выполняла всю работу, поэтому, если у вас уже есть индексированный столбец, это очень дешевая операция.

(обновление от 28.01.2016) Если вы хотите быть более строгими в определении медианы для четного числа элементов, это будет усреднять вместе значение двух средних значений.

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)
14 голосов
/ 03 июня 2009

Потому что медиана не является агрегатом SQL. См., Например, список агрегатных функций PostgreSQL и список агрегатных функций MySQL .

7 голосов
/ 03 июня 2009

Ну, причина , вероятно, заключается в том, что вам нужно отслеживать все числа, чтобы вычислить медиану. Avg, Count, Max, Min, StDev, Sum и Variance могут быть рассчитаны при постоянных потребностях хранения. То есть, как только вы «запишите» номер, он вам больше никогда не понадобится.

FWIW, переменные, которые нужно отслеживать: min, max, count, <n> = avg, <n^2> = avg квадрата значений.

2 голосов
/ 03 июня 2009

Я понятия не имею, какую базу данных вы используете, но если ваша база данных поддерживает другой агрегат, или вы можете найти умный способ сделать это, вы можете легко получить к нему доступ с помощью Агрегат .

2 голосов
/ 03 июня 2009

Вероятно, медиана не является частью стандартного SQL.

Кроме того, он требует сортировки, что делает его довольно дорогим для вычислений.

1 голос
/ 06 июля 2011

FWIW, вы можете расширить PostgreSQL 8.4 и выше, чтобы иметь медианную агрегатную функцию с этими фрагментами кода .

Другие фрагменты кода (которые работают для более старых версий PostgreSQL) показаны здесь . Обязательно прочтите комментарии к этому ресурсу.

...