вектор разреза по значениям NaN

data_test — это вектор, который заполняется числами с некоторым NaN.

data_test = [NaN, 2, 3, 4, NaN,NaN,NaN, 12 ,44, 34, NaN,5,NaN];

Я хотел бы вырезать data_test в соответствии с NaN и создать массив ячеек, содержащий части data_set между NaN.

data_cell{1}=[2 3 4];
data_cell{2}=[12 44 34];
data_cell{3}=[5];

на данный момент мне нужно отфильтровать эти значения (это нормально, просто в качестве примера отфильтрованные значения будут такими же, как и data_test +1)

data_cell{1} -> data_cell_filt{1}
data_cell{2} -> data_cell_filt{2}
data_cell{3} -> data_cell_filt{3}

и верните отфильтрованные значения в data_test.

data_cell_filt{1}
data_cell_filt{2} -> data_test
data_cell_filt{3}

для того, чтобы data_test был

data_test = [NaN, 3, 4, 5, NaN,NaN,NaN, 13 ,45, 35, NaN, 6, NaN];

ps (data_test в моем случае ~20000 элементов)


person gabboshow    schedule 12.06.2015    source источник


Ответы (3)


Вы можете легко сделать это с помощью цикла или использовать arrayfun следующим образом:

A = [NaN, 2, 3, 4, NaN, NaN, NaN, 13, 45, 35, NaN, 6, NaN]

i1 = find(diff(isnan(A))==-1)+1  %// Index where clusters of numbers begin 
i2 = find(diff(isnan(A))==1)     %// Index where clusters of numbers end

data_cell_filt = arrayfun(@(x,y)({A(x:y)}),i1,i2 ,'uni', false)
person Dan    schedule 12.06.2015
comment
предполагая, что я хочу использовать функцию smooth для фильтрации своих данных, как она будет встроена в arrayfun? - person gabboshow; 12.06.2015
comment
Предполагая, что ваша функция smooth принимает вектор, просто измените анонимную функцию на @(x,y)({smooth(A(x:y))}). Что касается того, чтобы вернуть его, вам нужно привести пример того, как это может выглядеть. - person Dan; 13.06.2015

Один подход с accumarray и cumsum и diff

%// find the index of regular numbers
idx = find(~isnan(data_test))

%// group the numbers which are adjacent, to some index number
idx1 = cumsum([1,diff(idx)~=1])

%// put all those numbers of same index number into a cell
out = accumarray(idx1.',data_test(idx).',[],@(x) {x.'})

Пример запуска:

data_test = [NaN, 2, 3, 4, NaN,NaN,NaN, 12 ,44, 34, NaN,5,NaN];

>> celldisp(out)
out{1} =
 2     3     4

out{2} =
12    44    34

out{3} =
 5
person Santhan Salai    schedule 12.06.2015
comment
Смело используйте accumarray здесь. +1. - person rayryeng; 12.06.2015

Подход на основе свертки:

ind = isnan(data_test);
t = conv(2*x-1, [-1 1], 'same'); %// convolution is like correlation but flips 2nd input
starts = find(t==2); %// indices of where a run of non-NaN's starts, minus 1
ends = find(t==-2);  %// indices of where it ends
result = mat2cell(data_test(~ind), 1, ends-starts); %// pick non-NaN's and split
person Luis Mendo    schedule 12.06.2015