Как рассчитать медиану в 1С 8 для Таблицы Значений?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С часто возникают задачи статистического анализа данных. Одной из самых популярных задач является поиск медианы — значения, которое разделяет выборку на две равные части. В отличие от среднего арифметического, медиана гораздо устойчивее к «выбросам» (экстремально низким или высоким значениям), что делает её незаменимой при анализе цен поставщиков, расчете средних зарплат или анализе времени выполнения заказов.

Рассмотрим подробно несколько способов реализации этого расчета: от классического алгоритма с использованием сортировки до применения встроенных инструментов статистического анализа платформы 1С.

Способ 1. Алгоритмический расчет через сортировку Таблицы Значений

Этот метод является универсальным и работает в любой версии 1С 8. Основная идея заключается в том, чтобы упорядочить данные по возрастанию и найти элемент, находящийся ровно посередине списка. Проанализируем нюансы: если количество строк нечетное, медианой будет центральное число; если четное — среднее арифметическое двух центральных чисел.

Разберем по шагам реализацию этого алгоритма:

  1. Создадим копию исходной ТаблицаЗначений, чтобы не нарушить порядок строк в основном алгоритме.
  2. Выполним сортировку по колонке с числовыми данными.
  3. Определим общее количество строк.
  4. Рассчитаем индекс центрального элемента (или элементов).

Посмотрим на пример кода, реализующий этот подход:


// Предположим, у нас есть ТЗДанных с колонкой "Цена"
ТЗКопия = ТЗДанных.Скопировать();
ТЗКопия.Сортировать("Цена Возр");

КолВоСтрок = ТЗКопия.Количество();

Если КолВоСтрок = 0 Тогда
    Медиана = 0;
ИначеЕсли КолВоСтрок % 2 = 1 Тогда
    // Нечетное количество: берем элемент ровно посередине
    ИндексСередины = (КолВоСтрок - 1) / 2;
    Медиана = ТЗКопия[ИндексСередины].Цена;
Иначе
    // Четное количество: среднее между двумя центральными
    Индекс2 = КолВоСтрок / 2;
    Индекс1 = Индекс2 - 1;
    Медиана = (ТЗКопия[Индекс1].Цена + ТЗКопия[Индекс2].Цена) / 2;
КонецЕсли;

Сообщить("Рассчитанная медиана: " + Медиана);

Важный момент: при расчете для четного количества строк результат может стать дробным. Убедитесь, что переменная Медиана или колонка, куда записывается результат, поддерживает нужную точность (минимум 2 знака после запятой).

Способ 2. Использование системного объекта «АнализДанных»

Платформа 1С предоставляет мощный встроенный механизм для статистического анализа. Объект АнализДанных с типом АнализДанныхОбщаяСтатистика позволяет получить медиану буквально в несколько строк кода, не заботясь о ручной сортировке и проверке на четность.

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

Рассмотрим пример реализации:


// Подготовим объект анализа
АнализДанных = Новый АнализДанных;
АнализДанных.ИсточникДанных = ТЗДанных; // Ваша Таблица Значений
АнализДанных.ТипАнализа = Тип("АнализДанныхОбщаяСтатистика");

// Выполняем расчет
РезультатАнализа = АнализДанных.Выполнить();

// Извлекаем медиану для конкретной колонки (например, "Цена")
// Путь к данным: НепрерывныеПоля -> ИмяКолонки -> Медиана
Медиана = РезультатАнализа.НепрерывныеПоля.Цена.Медиана;

Сообщить("Медиана через системный анализ: " + Медиана);

Этот метод предпочтительнее для чистого кода, однако стоит помнить, что объект АнализДанных может быть недоступен в некоторых специфических окружениях (например, в мобильном клиенте без соответствующих компонент), хотя в стандартных конфигурациях на сервере или в толстом клиенте он работает отлично.

Очистка данных от «выбросов» перед расчетом

Часто расчет медианы требуется для очистки данных от ошибок ввода или недобросовестных цен при парсинге сайтов. Как отмечали участники обсуждения, «нулевые» цены или «заградительные» цены (например, 999 999 руб.) сильно искажают статистику. Проанализируем методы, которые помогут сделать расчет еще точнее:

  1. Правило трех сигм: отсечение значений, которые отклоняются от среднего более чем на три среднеквадратичных отклонения. Однако этот метод лучше работает для нормального распределения.
  2. Метод Тьюки (Межквартильный размах): Вычислите 25-й и 75-й процентили (через тот же АнализДанных). Разница между ними — это IQR. Удалите всё, что ниже Q1 - 1.5*IQR или выше Q3 + 1.5*IQR.
  3. Простое процентильное отсечение: удаление 5% самых низких и 5% самых высоких значений перед расчетом итоговой медианы.

Рассмотрим пример простого отсечения краев выборки в 1С:


// Отсекаем по 10% с каждой стороны
КоличествоДляУдаления = Целое(ТЗКопия.Количество() * 0.1);

Для Сч = 1 По КоличествоДляУдаления Цикл
    ТЗКопия.Удалить(0); // Удаляем самое маленькое
    ТЗКопия.Удалить(ТЗКопия.Количество() - 1); // Удаляем самое большое
КонецЦикла;

// Далее считаем медиану по остатку, как в Способе 1

Сравнение методов: что выбрать?

Выясним, какой метод лучше подходит для ваших задач. Если вам нужно быстро посчитать только медиану в небольшом отчете, Способ 1 (Сортировка) будет самым понятным и легко отлаживаемым. Если же вы занимаетесь серьезным анализом данных, прогнозированием спроса или обработкой больших прайс-листов, настоятельно рекомендуем освоить Способ 2 (АнализДанных). Он предоставляет доступ к таким параметрам, как Дисперсия, СреднеквадратическоеОтклонение и Квартили, что позволит вам построить гораздо более качественную модель обработки данных.

Посмотрим на итоговый совет: всегда проверяйте данные на NULL и тип Число перед началом расчетов, так как встроенные методы сортировки и анализа чувствительны к типам данных в колонках ТаблицаЗначений. Использование ОписаниеТипов при создании таблицы — залог стабильной работы ваших алгоритмов.

← На главную