Tomasina
@Tomasina
Инженер-разработчик

Как отбросить выбивающиеся элементы из потока схожих (фильтрация входных данных)?

есть такой входной поток:
400f03476e4346a2b104417025f251cd.png

Как можно выделить из этого два наиболее встречающихся числа из трех, для каждого сенсора?
Т.е. в данном случае получить тройки [*, 53, 27], [*, 46, 37], [2, 17 *], [*, 95, 51].

Сейчас используется среднее арифметическое, но из-за случайных всплесков отклонение от "эталона" получается более 3 единиц, что не устраивает: получается [25, 53, 25], [32, 46, 33], [5, 17, 4], [54, 95, 52].

Грубо говоря, из 200 чисел в каждой колонке надо отбросить явно случайные всплески, которые сильно отличаются от остальных, затем найти для каждой колонки число с максимальной частотой появления (плюс-минус допустимая погрешность) и выбрать из каждой тройки два наиболее часто встречающихся числа.

Как называются такие алгоритмы? В частности, с языке C++.
  • Вопрос задан
  • 185 просмотров
Пригласить эксперта
Ответы на вопрос 2
Могу предложить тупое решение.
Накапливайте кол-во встречающихся чисел, например, в std::map<int, std::size_t>
std::map<int, std::size_t> m;
for (int v : vals) { ++m[v]; }
std::vector<std::pair<int, std::size_t> > v(m.begin(), m.end());
std::sort(v.begin(), v.end(), [] (std::pair<int, std::size_t> const & l, std::pair<int, std::size_t> const & r) { return l.second > r.second; });
// в v пары "число - кол-во таких чисел", отсортированы по убыванию
// можно откинуть нижнюю часть (те, которые встречаются реже, чем какой-то процент, например, 10%)
v.erase(
  std::find_if(v.begin(), v.end(), [] (std::pair<int, std::size_t> const & x) { return x.second < (v.size() / 10); }),
  v.end());
// а сверху взять часто встречающиеся
int row_value = v.front().first;
Ответ написан
Комментировать
Tomasina
@Tomasina Автор вопроса
Инженер-разработчик
Положение спас медианный фильтр, при глубине 10-20 итераций все лишнее замечательно отсекается.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы