Как обозначить несколько усреднённых значений в общем количестве всех значений?

 

есть числа, допустим

1,3,4,6,10,13,14,15,19,24,26,33

Числа 10,19,33 стоят особняком, а остальные числа находятся рядом друг с другом. 

Как можно рассчитать средние значения всех плотностоящих друг к другу групп чисел, отсеяв обособленные? 

Например, чтобы посчиталось среднее значение первой группы (1+3+4+6), второй группы (13+14+15) и третьей (24+26)

То есть, найти наиболее "активные" числовые места, при этом чтобы в расчёт среднего не попадали наиболее отдалённые от плотных групп числа

Не соображу, как организовать это в коде

 

Здесь, как всегда, проблема определения "особняка". В лоб решается установкой минимального расстояния до других близлежащих чисел. В приведенном случае это значение 2. То есть если расстояние до соседних значений больше, чем 2, то число обособленное.

Можно пойти и по другому пути, расчетному. Составить таблицу разностей всех соседних значений. Из нее выделить наиболее редко встречающиеся разности. Наименьшую из редко встречающихся разностей взять в качестве минимального расстояния.

 
Ihor Herasko #:

Здесь, как всегда, проблема определения "особняка". В лоб решается установкой минимального расстояния до других близлежащих чисел. В приведенном случае это значение 2. То есть если расстояние до соседних значений больше, чем 2, то число обособленное.

Можно пойти и по другому пути, расчетному. Составить таблицу разностей всех соседних значений. Из нее выделить наиболее редко встречающиеся разности. Наименьшую из редко встречающихся разностей взять в качестве минимального расстояния.

Интересно, спасибо

 
Ivan Butko:

есть числа, допустим

1,3,4,6,10,13,14,15,19,24,26,33

Числа 10,19,33 стоят особняком, а остальные числа находятся рядом друг с другом. 

Как можно рассчитать средние значения всех плотностоящих друг к другу групп чисел, отсеяв обособленные? 

Например, чтобы посчиталось среднее значение первой группы (1+3+4+6), второй группы (13+14+15) и третьей (24+26)

То есть, найти наиболее "активные" числовые места, при этом чтобы в расчёт среднего не попадали наиболее отдалённые от плотных групп числа

Не соображу, как организовать это в коде

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

 
Vladimir #:

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

Загуглил медиану... формула сложная

 
Ivan Butko #:

Загуглил медиану... формула сложная

Да вроде там нет никакой формулы... Медиана ведь - это значение, больше и меньше которого одинаковое количество членов числового ряда. Получается, что алгоритм таков:

  1. Отсортировать массив. По возрастания или убыванию, без разницы.
  2. Если количество членов числового ряда нечетное, то медиана - значение среднего элемента массива. Если четное, то среднее между двумя средними элемента массива.
double GetMedian(double &arrRow[])
{
   ArraySort(arrRow);

   int nTotal = ArraySize(arrRow);
   if (nTotal == 0)
      return 0.0;

   if (nTotal % 2 == 1)
      return arrRow[nTotal / 2];

   return (arrRow[nTotal / 2] + arrRow[nTotal / 2 - 1]) / 2.0;
}


Только вот для поставленной задачи, на мой взгляд, медиана никак не поможет.
 
void OnStart() {
    int deviation = 2; // максимальное отклонение
    // отсортированный массив
    int numbers[] = {1,3,4,6,10,13,14,15,19,24,26,33};
    int groups[ArraySize(numbers)] ; // индексы групп
    int indexGroup = 1; // индекс текущей группы
    
    groups[0] = indexGroup;
    for(int j = 1; j < ArraySize(numbers); j++) {
        if (numbers[j] - numbers[j - 1] > deviation)
            indexGroup++;
        groups[j] = indexGroup;
        PrintFormat("num = %i group = %i", numbers[j], groups[j]);
    }
}

/*
num = 3 group = 1
num = 4 group = 1
num = 6 group = 1
num = 10 group = 2
num = 13 group = 3
num = 14 group = 3
num = 15 group = 3
num = 19 group = 4
num = 24 group = 5
num = 26 group = 5
num = 33 group = 6
*/
 

Можно попробовать поиграть с логарифмическим масштабом. Он может схлопнуть значения, а рамки одной шкалы например от 1 до 10. Преимущество заключается в то, что шкала подстраивается под максимальное значение. Недостаток: Логарифм от 1 = 0

За счет этого значения могут стоять плотнее в зависимости от максимального значения. Окрестности же можно определять динамически от количества общего или по максимальной плотности.

Пример шкалы и значений


На нем видно что группы значений находятся в пределах 1-2х пунктов шкалы друг от друга - дальше можно выбирать точность.

Сам метод 

Метод

 

"Числа 10,19,33 стоят особняком, а остальные числа находятся рядом друг с другом. 

Как можно рассчитать средние значения всех плотностоящих друг к другу групп чисел, отсеяв обособленные? "

Заметьте, в Вашей задаче вообще не освещено понятие близости чисел. Друг к другу, к группе - это необязательно одинаковые понятия. О разнообразии этих понятий и соответствующих алгоритмов выявления групп см., например, https://habr.com/ru/post/101338/. Уже на уровне дипломной работы видно, что алгоритмов много. Главное здесь целеполагание, а реализовать достижение цели (какой-либо группировки чисел) в алгоритме и коде намного проще. И отбрасывание обособленных становится простым и понятным, если известно, что такое обособленность - то есть как вычислить расстояние от числа до группы, кого включать в группу. Кстати, Вы не сообщили, что следует брать в качестве "среднего значения групп чисел" - среднее арифметическое центров групп или как? Это тоже целеполагание. Не зная сути задачи, трудно чем-либо помочь, но все же скажу, что лучшим способом усреднения (если интересна не сумма, а отдельные реализации) и сглаживания является медианное. Оно устойчиво к выбросам, а среднее арифметическое сдвигается в их сторону (в сторону "обособленных").

Разницу поясню на примере средней зарплаты. Росстат перешел на ее вычисление не как среднеарифметической, а как медианы имеющихся на предприятии или в отрасли зарплат. Директор 500 тыс, 9 работников по 50 тыс, в среднем 95 тыс - арифметическое усреднение, медианное дает 50 тыс., это более целесообразная оценка при выборе места работы. В то же время для прибыли иначе: с одной из продаж 500 тыс, и еще с 9 продаж по 50 тыс., в среднем 95 тыс - более целесообразная оценка, так как важна именно суммарная прибыль, и именно из нее выплачиваются премия, дивиденды и отчисления на базу отдыха и детский летний лагерь.

Пользуйтесь каналами и групповыми чатами MQL5.community
Пользуйтесь каналами и групповыми чатами MQL5.community
  • www.mql5.com
На сайте MQL5.com встречаются трейдеры со всего мира — публикуют статьи, бесплатные коды и продукты в Маркете, выполняют работы на фриланс бирже и копируют торговые сигналы. Вы можете общаться с ними на форуме, в трейдерские чатах и каналах MetaTrader.
Причина обращения: