Отсутствует "медианная" Агрегатная функция в Django?

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

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

6 ответов


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


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

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

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

(обновление 1/28/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)

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

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


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

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


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


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

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