【问题标题】:cut vector according to NaN values根据 NaN 值切割向量
【发布时间】:2015-08-28 16:52:56
【问题描述】:

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 个元素)

【问题讨论】:

    标签: matlab nan partition


    【解决方案1】:

    基于卷积的方法:

    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
    

    【讨论】:

      【解决方案2】:

      accumarraycumsumdiff 的一种方法

      %// 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
      

      【讨论】:

      • 在此处智能使用accumarray。 +1。
      【解决方案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)
      

      【讨论】:

      • 假设我想使用smooth函数过滤我的数据,如何嵌入到arrayfun中?
      • 假设您的smooth 函数接受一个向量,那么只需将匿名函数更改为@(x,y)({smooth(A(x:y))})。至于“把它放回去”,你需要提供一个例子来说明它的外观
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 2021-03-06
      相关资源
      最近更新 更多