我有一个冗长的数字数据向量,这里和那里有一些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之间。
答案 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