我有一个像这样的矩阵:
A(a,b)=
NaN 1 1
NaN 2 NaN
NaN 3 1
NaN 4 2
NaN 5 3
NaN 6 4
NaN 7 5
NaN 8 6
NaN 9 NaN
NaN 10 NaN
NaN NaN NaN
NaN NaN 1
NaN NaN 2
NaN NaN 3
NaN NaN NaN
我希望获得一个矩阵(逻辑或数字),其中1被分配给没有NaN的所有值,并且每当达到某个值时,比如5。但是(这里是困难的部分)1必须同时分配给5之前的数字(从1到5),再次当且仅当达到5时。 因此,我的预期结果应该是如下矩阵:
B(a,b) =
0 1 0
0 1 0
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 0
0 1 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
请问一些想法? 评论后的其他信息: 我正在考虑订单栏明智。每列中的每个数字运行始终从1开始,并以1,2,3的形式继续,... NaN将停止此序列,何时重启将从1重新启动。 如果两个NaN之间的序列包含指定值,那么前NN和后NaN之间的所有条目必须为真(值= 1)(参见第3列)
答案 0 :(得分:1)
将您的数据矩阵定义为
A = [NaN 1 1
NaN 2 NaN
NaN 3 1
NaN 4 2
NaN 5 3
NaN 6 4
NaN 7 5
NaN 8 6
NaN 9 NaN
NaN 10 NaN
NaN NaN NaN
NaN NaN 1
NaN NaN 2
NaN NaN 3
NaN NaN NaN];
这是一种使用正则表达式检测至少5个数值的运行的方法:
B = mat2cell(char(~isnan(A).'+'0'),ones(size(A,2),1)); %'// make a string from each column
C = regexprep(B, '(1{5}1*)', '${repmat(''+'',1,numel($0))}'); %// change that 5 as needed
result = vertcat(C{:}).'=='+';
这给出了
result =
0 1 0
0 1 0
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 1
0 1 0
0 1 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
答案 1 :(得分:0)
以下代码效率不高但完成工作。如果您需要高效的代码,其他可能更合适。但是,这就是诀窍:
function stackoverflow
A =[
NaN 1 1
NaN 2 NaN
NaN 3 1
NaN 4 2
NaN 5 3
NaN 6 4
NaN 7 5
NaN 8 6
NaN 9 NaN
NaN 10 NaN
NaN NaN NaN
NaN NaN 1
NaN NaN 2
NaN NaN 3
NaN NaN NaN];
[n,m] = size(A);
k= 5;
B =(A>=k);
for j=1:m % for all rows
for i=1:n % for all columns
if B(i,j)==1 % if the value is >=5, all 4 prior values also have to be 1
B(i-(k-1):i,j) =1;
end
end
end
disp(A)
disp(B)
但是我很确定,有一种方法可以摆脱循环,我现在无法弄清楚。