Еще один способ вычисления медианы запросом 1С

09.08.21

Разработка - Запросы

Вниманию сообщества предлагается еще один способ расчета медианы числового ряда одним пакетным запросом 1С.

Гуглинг и инфостартинг не выдали автору статьи ответа – был ли этот способ когда-либо реализован на языке запросов 1С или нет. Если описание реализации такого способа для 1С уже есть – прошу ссылку казать в комментариях.

 
Лирическое отступление

В начале, как и положено -

Сухая теория

Согласно википедии, у понятия «медиана» есть два определения:

  1. Медиана (от лат. mediāna «середина») набора чисел — число, которое находится в середине этого набора, если его упорядочить по возрастанию, то есть такое число, что половина из элементов набора не меньше него, а другая половина не больше.
  2. Медиана набора чисел — это число, сумма расстояний (или, если более строго, модулей) от которого до всех чисел из набора минимальна

В дальнейших рассуждениях будем опираться на первое определение. Но не только потому, что оно проще в восприятии.

Алгоритм вычисления медианы по этому определению прост и состоит из следующих шагов:

  1. пусть нам дан некоторый числовой ряд из N чисел
  2. упорядочиваем этот ряд по возрастанию значений
  3. если N – нечетное, то
    1. вычисляем индекс i = Целое(1 + N/2)
    2. находим число ni, стоящее на месте с индексом i
    3. найденное число и есть искомая медиана
  4. если N – четное
    1. вычисляем два индекса – i и j, где i = N / 2, j = i + 1
    2. и вот тут есть три варианта:
      1. объявляем медианой число ni
      2. объявляем медианой число nj
      3. объявляем медианой среднее арифметическое этих чисел
 
Примеры

 В этих примерах будем считать, что индексация ряда начинается с 1

Пример ряда с нечетным количеством элементов

  1. Пусть дан числовой ряд {7, 15, 6, 8, 7, 7, 15}
  2. упорядочим ряд по возрастанию значений: {6, 7, 7, 7, 8, 15, 15}
  3. ряд содержит 7 чисел (N = 7), значит i = Целое (1 + 7/2) = 4
  4. медиана ряда - число i4 = 7

Пример ряда с четным количеством элементов

  1. Пусть дан числовой ряд {7, 15, 6, 8, 7, 7, 20, 15}
  2. упорядочим ряд по возрастанию значений: {6, 7, 7, 7, 8, 15, 15, 20}
  3. ряд содержит 8 чисел (N = 8), значит
    1. i = 8/2 = 4
    2. j = i + 1 = 5
  4. медианой этого числового ряда могут быть следующие числа:
    1. i4 = 7
    2. i5 = 8
    3. Среднее(7, 8) = (7 + 8) / 2 = 7.5

Теоретически вроде просто.

Но на практике при попытке реализации этого алгоритма методом «в лоб» на языке запросов 1С возникает одна непростая задача – индексация элементов ряда: в языке запросов 1С нет легких и быстрых способов пронумеровать элементы числового ряда. Задача нумерации элементов ряда еще более осложняется, если в этом ряду есть дубликаты.
Способ, предлагаемый вниманию сообщества, избавляет нас от необходимости индексировать числовой ряд.

Описание предлагаемого способа

Даже больше - этот способ не предусматривает упорядочивание ряда по возрастанию значений его элементов!

Что же такого хитрого в этом способе?

Все дело в индексах элементов упорядоченного числового ряда.

Возможно, это звучит парадоксально – ряд мы не упорядочиваем, но опираемся на индексы упорядоченного ряда. Но это так.

Для рассмотрения возьмем числовой ряд из первого примера - {7, 15, 6, 8, 7, 7, 15}.

И проделаем с ним следующие манипуляции:

- упорядочим - {6, 7, 7, 7, 8, 15, 15}.

- проиндексируем упорядоченный ряд:

n1 = 6

n2 = 7

n3 = 7

n4 = 7

n5 = 8

n6 = 15

n7 = 15

- выделим уникальные элементы ряда: {6, 7, 8 ,15}

- определим диапазоны индексов, которые занимают уникальные элементы ряда в упорядоченном ряду:

6 – [1, 1]

7 – [2, 4]

8 – [5, 5]

15 – [6, 7].

И вот тут мне кажется, что Вы, мой внимательный читатель, уже поняли основную суть!

Совершенно верно: зная индекс среднего элемента ряда нам необходимо всего лишь определить:

- в какой диапазон этот индекс попадает

- и какой элемент ряда занимает этот диапазон.

Т.е. для нашего примера индекс среднего элемента упорядоченного ряда равен 4.

Этот индекс входит в диапазон [2, 4].

Число, занимающее этот диапазон – 7.

Это число – и есть медиана нашего числового ряда.

 

Подытожим – в предлагаемом способе для вычисления медианы нам необходимо всего лишь:

- иметь диапазоны индексов, которые занимают уникальные элементы ряда в упорядоченном ряду

- знать индекс среднего элемента ряда!

И то, и другое уже можно реализовать на языке запросов 1С.

От теории к практике

Настало время продемонстрировать запрос 1С, реализующий предложенный способ.

Небольшое уточнение: для ряда, содержащего четное количество элементов, предлагаемый запрос в качестве медианы вычисляет среднее арифметическое элементов ni и nj

Вот он:

ВЫБРАТЬ     7 КАК Элемент
ПОМЕСТИТЬ Ряд
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    15
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    6
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    8
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    7
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    7
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ    15

;
////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ
    КОЛИЧЕСТВО(Ряд.Элемент) КАК Длина
ПОМЕСТИТЬ ДлинаРяда
ИЗ
    Ряд КАК Ряд
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВЫРАЗИТЬ((ДлинаРяда.Длина - 1) / 2 - 0.1 КАК ЧИСЛО(19, 0)) КАК Индекс
ПОМЕСТИТЬ ИндексМедианногоЭлемента
ИЗ
    ДлинаРяда КАК ДлинаРяда

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    ВЫРАЗИТЬ((ДлинаРяда.Длина - 1) / 2 КАК ЧИСЛО(19, 0))
ИЗ
    ДлинаРяда КАК ДлинаРяда
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Ряд.Элемент КАК Элемент,
    КОЛИЧЕСТВО(Ряд.Элемент) КАК Количество
ПОМЕСТИТЬ СтатистикаРяда
ИЗ
    Ряд КАК Ряд

СГРУППИРОВАТЬ ПО
    Ряд.Элемент
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Окончание.Элемент КАК Элемент,
    ЕСТЬNULL(СУММА(Начало.Количество), 0) КАК НачальныйИндекс,
    ЕСТЬNULL(СУММА(Начало.Количество), 0) + Окончание.Количество - 1 КАК КонечныйИндекс
ПОМЕСТИТЬ ИндексыЭлементов
ИЗ
    СтатистикаРяда КАК Начало
        ПРАВОЕ СОЕДИНЕНИЕ СтатистикаРяда КАК Окончание
        ПО Начало.Элемент < Окончание.Элемент

СГРУППИРОВАТЬ ПО
    Окончание.Элемент,
    Окончание.Количество
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СРЕДНЕЕ(ИндексыЭлементов.Элемент) КАК Элемент
ИЗ
    ИндексМедианногоЭлемента КАК ИндексМедианногоЭлемента
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ИндексыЭлементов КАК ИндексыЭлементов
        ПО (ИндексМедианногоЭлемента.Индекс МЕЖДУ ИндексыЭлементов.НачальныйИндекс И ИндексыЭлементов.КонечныйИндекс)

 

Запрос достаточно прост и вряд ли нуждается в комментировании.

Медиана запрос интервал статистика

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

10000 руб.

02.09.2020    131386    713    390    

761

Как посмотреть итоговый запрос в отчете СКД

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    3706    implecs_team    6    

37

Пропорциональное распределение в запросе с использованием АвтоНомерЗаписи()

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Часто поступают задачи по произвольному распределению общих сумм. После распределения иногда пропадают копейки. Суть решения добавить АвтоНомерЗаписи() в ВТ распределения, и далее используя функции МАКСИМУМ или МИНИМУМ можем положить разницу копеек в первую или последнюю строку знаменателя распределения.

11.04.2024    2667    andrey_sag    10    

32

Для чего используют конструкцию запроса "ГДЕ ЛОЖЬ" в СКД на примере конфигурации 1С:ERP

Запросы СКД Программист Стажер Платформа 1С v8.3 Запросы Система компоновки данных 1С:ERP Управление предприятием 2 Бесплатно (free)

В типовых конфигурациях разработчики компании 1С иногда используют в отчетах, построенных на СКД, такую конструкцию, как "ГДЕ ЛОЖЬ". Такая конструкция говорит о том, что данные в запросе не будут получены совсем. Для чего же нужен тогда запрос?

13.02.2024    6353    KawaNoNeko    23    

26

Набор-объект для СКД по тексту или запросу

Запросы СКД Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Есть список полей в виде текста, или запрос - закидываем в набор СКД.

1 стартмани

31.01.2024    2332    2    Yashazz    0    

32

Запрос 1С copilot

Инструментарий разработчика Запросы Программист Стажер Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Бесплатно (free)

Пишем на человеческом языке, что нам надо, и получаем текст запроса на языке 1С. Используются большие языковые модели (LLM GPT) от OpenAI или Яндекс на выбор.

15.01.2024    7258    45    mkalimulin    32    

54

PrintWizard: поддержка представлений ЗУП в конструкторе

Инструментарий разработчика Запросы Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Одной из интересных задач, стоящих в процессе разработки, была поддержка механизма представлений в ЗУП. Но не просто возможность исполнения запросов с ними. Основная проблема была в том, чтобы с ними было удобно работать, а именно: создавать, модифицировать и отлаживать. Кратко о том, что в итоге получилось...

14.12.2023    2045    vandalsvq    7    

29

Консоль запросов УФ 8.3.2.24.12 (мод от Dr.Zombi)

Инструментарий разработчика Запросы Программист Платформа 1С v8.3 Управляемые формы Запросы Россия Абонемент ($m)

Работа с запросом и СКД, Полная поддержка пакетных запросов, временных таблиц. Главное скорость отладки запроса и данных, а красота вторична.

1 стартмани

07.12.2023    3522    52    DrZombi    54    

21
Оставьте свое сообщение