根据 NaN 值切割向量
cut vector according to NaN values
data_test 是一个由带有一些 NaN 的数字填充的向量。
data_test = [NaN, 2, 3, 4, NaN,NaN,NaN, 12 ,44, 34, NaN,5,NaN];
我想根据 NaN 剪切 data_test
并创建一个元胞数组,其中包含 NaN 之间的 data_set
片段。
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 个元素)
您可以通过循环轻松完成,或者像这样使用 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)
accumarray
and cumsum
and 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
基于卷积的方法:
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
data_test 是一个由带有一些 NaN 的数字填充的向量。
data_test = [NaN, 2, 3, 4, NaN,NaN,NaN, 12 ,44, 34, NaN,5,NaN];
我想根据 NaN 剪切 data_test
并创建一个元胞数组,其中包含 NaN 之间的 data_set
片段。
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 个元素)
您可以通过循环轻松完成,或者像这样使用 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)
accumarray
and cumsum
and 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
基于卷积的方法:
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