Matlab:找到被NaN包围的小岛数

时间:2014-08-26 05:12:33

标签: regex matlab nan convolution

我有一个冗长的数字数据向量,这里和那里有一些NaN序列。大多数NaN都是大块的,但有时NaN的各个部分靠得很近,形成了由NaN围绕的数字岛,如下所示:

...NaN 1 2 3 5  ... 9 4 2 NaN...

我想找到大小在1到15000个元素之间的所有数据孤岛,并用坚固的NaN块替换它们。

我尝试了一些事情,但是存在一些问题 - 数据集很大,因此将其转换为字符串并使用正则表达式来执行:

[found start end] = regexp(num2str(isnan(data)),'10{1,7}1','match','start','end')

是不可能的,因为执行num2str(isnan(数据))需要花费太长时间。所以我需要一种数字方法来查找所有NaN数 - Nan,其中数字的数量在1到15000之间。

1 个答案:

答案 0 :(得分:2)

以下是如何执行此操作的示例:

% generate random data
data            = rand(1,20)
data(data>0.5)  = NaN

% add NaN before and after the original array
% for easier detection of the numerical block
% starting at 1st element and finishing at the last one
datatotest      = [ NaN data NaN ];

NumBlockStart   = find( ~isnan(datatotest(2:end))   & isnan(datatotest(1:end-1)) )+0
NumBlockEnd     = find( ~isnan(datatotest(1:end-1)) & isnan(datatotest(2:end))   )-1
NumBlockLength  = NumBlockEnd - NumBlockStart + 1

在此示例中,NumBlockStart包含数字块的起始索引,NumBlockEnd包含数字块的最后一个索引。 NumBlockLength包含每个块的长度。 现在你可以随心所欲地做任何事情:)

这是可能的输出

data =
0.0382    0.3767    0.8597    0.2743    0.6276    0.2974    0.2587    0.8577    0.8319    0.1408    0.9288    0.0990    0.7653    0.7806    0.8576    0.8032    0.8340    0.1600    0.4937    0.7784

data =
0.0382    0.3767       NaN    0.2743       NaN    0.2974    0.2587       NaN       NaN    0.1408       NaN    0.0990       NaN       NaN       NaN       NaN       NaN    0.1600    0.4937       NaN

NumBlockStart =
 1     4     6    10    12    18

NumBlockEnd =
 2     4     7    10    12    19

NumBlockLength =
 2     1     2     1     1     2

<强> UPDATE1

这是更高效的版本:

data            = rand(1,19)
data(data>0.5)  = NaN

test2           = diff( ~isnan([ NaN data NaN ]) );
NumBlockStart   = find( test2>0 )-0
NumBlockEnd     = find( test2<0 )-1
NumBlockLength  = NumBlockEnd - NumBlockStart + 1