Это проблема, которую трудно решить вообще; Ваше окончательное решение будет зависеть от процесса и уникально для вашей ситуации.
При этом вам нужно начать с понимания ваших данных: от одного образца к другому, какой вариант возможен? Используя это, вы можете использовать предыдущие выборки данных (и, возможно, будущие выборки данных), чтобы решить, является ли текущая выборка фиктивной или нет. Затем вы получите фильтр, который выглядит примерно так:
const int MaxQueueLength = 100; // adjust these two values as necessary
const double MaxProjectionError = 5;
List<double> FilterData(List<double> rawData)
{
List<double> toRet = new List<double>(rawData.Count);
Queue<double> history = new Queue<double>(MaxQueueLength); // adjust queue length as necessary
foreach (double raw_Sample in rawData)
{
while (history.Count > MaxQueueLength)
history.Dequeue();
double ProjectedSample = GuessNext(history, raw_Sample);
double CurrentSample = (Math.Abs(ProjectedSample - raw_Sample) > MaxProjectionError) ? ProjectedSample : raw_Sample;
toRet.Add(CurrentSample);
history.Enqueue(CurrentSample);
}
return toRet;
}
Итак, волшебство приходит с вашей функцией GuessNext. Здесь вы разберетесь с вещами, специфичными для вашей ситуации, и должны учитывать все, что вам известно о процессе сбора данных. Существуют ли физические ограничения на то, как быстро может измениться ввод? Имеют ли ваши данные неверные значения, которые вы можете легко отфильтровать?
Вот простой пример для функции GuessNext, которая работает от первой производной ваших данных (т. Е. Предполагается, что ваши данные представляют собой примерно прямую линию, когда вы смотрите только на их небольшой участок)
double lastSample = double.NaN;
double GuessNext(Queue<double> history, double nextSample)
{
lastSample = double.IsNaN(lastSample) ? nextSample : lastSample;
//ignore the history for simple first derivative. Assume that input will always approximate a straight line
double toRet = (nextSample + (nextSample - lastSample));
lastSample = nextSample;
return toRet;
}
Если ваши данные особенно шумные, вы можете применить к ним фильтр сглаживания, прежде чем передавать его в GuessNext. Вам просто нужно потратить некоторое время на алгоритм, чтобы придумать что-то, что имеет смысл для ваших данных.
Данные вашего примера выглядят параметрическими в том смысле, что каждый образец определяет значения X и Y. Возможно, вы сможете применить вышеупомянутую логику к каждому измерению независимо, что было бы целесообразно, если бы только одно измерение дало вам неправильные числа. Это может быть особенно успешным в тех случаях, когда, например, одно измерение является отметкой времени, а отметка времени иногда является фиктивной.