MATLAB: Использование интерполяции для замены отсутствующих значений (NAN)

StackOverflow https://stackoverflow.com/questions/3628957

Вопрос

У меня есть массив клеток, каждый из которых содержит последовательность значений как вектор строки. Последовательности содержат некоторые недостающие значения, представленные NaN.

Я хотел бы заменить все назы, используя какой-то метод интерполяции, как я могу сделать это в MatLab? Я также открыт для других предложений о том, как иметь дело с этими недостающимися ценностями.

Рассмотрим эти данные образца для иллюстрации проблемы:

seq = {randn(1,10); randn(1,7); randn(1,8)};
for i=1:numel(seq)
    %# simulate some missing values
    ind = rand( size(seq{i}) ) < 0.2;
    seq{i}(ind) = nan;
end

Полученные последовательности:

seq{1}
ans =
     -0.50782     -0.32058          NaN      -3.0292     -0.45701       1.2424          NaN      0.93373          NaN    -0.029006
seq{2}
ans =
      0.18245      -1.5651    -0.084539       1.6039     0.098348     0.041374     -0.73417
seq{3}
ans =
          NaN          NaN      0.42639     -0.37281     -0.23645       2.0237      -2.2584       2.2294

Редактировать:

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

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

Это было полезно?

Решение

Ну, если вы работаете со данными серии Time-Serice, вы можете использовать встроенную функцию интерполяции MATLAB.

Что-то вроде этого должно работать на вашу ситуацию, но вам нужно адаптировать его немного ... т. Е. Если у вас нет равных разнесенных отборов, вам нужно изменить times линия.

nseq = cell(size(seq))
for i = 1:numel(seq)
    times = 1:length(seq{i});
    mask =  ~isnan(seq{i});
    nseq{i} = seq{i};
    nseq{i}(~mask) = interp1(times(mask), seq{i}(mask), times(~mask));

end

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

Другие советы

я хотел бы использовать inpaint_nans., инструмент, предназначенный для замены элементов NAN в 1-D или 2-D матрицах интерполяции.

seq{1} = [-0.50782 -0.32058 NaN -3.0292 -0.45701 1.2424 NaN 0.93373 NaN -0.029006];
seq{2} = [0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417];
seq{3} = [NaN NaN 0.42639 -0.37281 -0.23645 2.0237];

for i = 1:3
  seq{i} = inpaint_nans(seq{i});
end

seq{:}
ans =
 -0.50782 -0.32058 -2.0724 -3.0292 -0.45701 1.2424 1.4528 0.93373 0.44482 -0.029006

ans =
  0.18245 -1.5651 -0.084539 1.6039 0.098348 0.041374 -0.73417

ans =
  2.0248 1.2256 0.42639 -0.37281 -0.23645 2.0237

Если у вас есть доступ к Индикатор идентификации системы, вы можете использовать Мидтата Функция для оценки пропущенных значений. Согласно документация:

Эта команда линейно интерполизирует отсутствующие значения для оценки первой модели. Затем он использует эту модель для оценки пропущенных данных в качестве параметров путем минимизации ошибок прогнозирования вывода, полученных из реконструированных данных.

В основном алгоритм чередуется между оценкой отсутствующих данных и оценки моделей, как аналогично алгоритму максимизации ожидания (EM) ожидания.

Предполагается, что модель может быть любой из линейных моделей idmodel (AR / ARX / ..), или если не дан, использует модель состояния состояния по умолчанию.

Вот как применить его к вашим данным:

for i=1:numel(seq)
    dat = misdata( iddata(seq{i}(:)) );
    seq{i} = dat.OutputData;
end

Использовать GridDedinterPolant

Там также некоторые другие функции, такие как Interp1. Для изогнутых участков SPLINE - лучший метод, чтобы найти недостающие данные.

Как говорит Дудоулд, вам нужно взять на себя какие-то отношения между вашими данными.

Один тривиальный вариант будет вычислять среднее значение вашей общей серии и использовать те для отсутствующих данных. Другой тривиальный вариант будет предпринять среднее значение n предыдущих и n следующих значений.

Но будьте очень осторожны.

Рассмотрим следующий пример

X = немного массива nx1 y = f (x) с некоторыми назами в нем

затем использовать

X1 = x (найти (~ isnan (y))); Y1 = y (найти (~ isnan (y)));

Теперь интерполизируйте над X1 и Y1, чтобы вычислить все значения вообще X.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top