我有一個由一和零組成的二維矩陣。
mat = [0 0 0 0 1 1 1 0 0
1 1 1 1 1 0 0 1 0
0 0 1 0 1 1 0 0 1];
我需要在每一行中找到所有連續重復的重復,并且僅當序列大小小于 5(5 個連續的)時才用零替換所有重復:
mat = [0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0];
任何有關如何解決此問題的建議都將受到歡迎。
uj5u.com熱心網友回復:
您可以使用diff查找 1 的運行的起點和終點,以及基于此的一些邏輯將太短的運行歸零。請參閱下面的代碼以及相關的注釋
% Input matrix of 0s and 1s
mat = [0 0 0 0 1 1 1 0 0
1 1 1 1 1 0 0 1 0
0 0 1 0 1 1 0 0 1];
% Minimum run length of 1s to keep
N = 5;
% Get the start and end points of the runs of 1. Add in values from the
% original matrix to ensure that start and end points are always paired
d = [mat(:,1),diff(mat,1,2),-mat(:,end)];
% Find those start and end points. Use the transpose during the find to
% flip rows/cols and search row-wise relative to input matrix.
[cs,r] = find(d.'>0.5); % Start points
[ce,~] = find(d.'<-0.5); % End points
c = [cs, ce]; % Column number array for start/end
idx = diff(c,1,2) < N; % From column number, check run length vs N
% Loop over the runs which didn't satisfy the threshold and zero them
for ii = find(idx.')
mat(r(ii),c(ii,1):c(ii,2)-1) = 0;
end
如果你想把易讀性拋到窗外,可以根據完全相同的邏輯將其壓縮為稍微更快、更密集的版本:
[c,r] = find([mat(:,1),diff(mat,1,2),-mat(:,end)].'); % find run start/end points
for ii = 1:2:numel(c) % Loop over runs
if c(ii 1)-c(ii) < N % Check if run exceeds threshold length
mat(r(ii),c(ii):c(ii 1)-1) = 0; % Zero the run if not
end
end
uj5u.com熱心網友回復:
@Wolfie 的矢量化解決方案簡潔明了,但有點難以理解,而且與問題的措辭相去甚遠。這是使用回圈的問題的直接翻譯。它的優點是更容易理解,并且記憶體分配更少,速度稍快,這意味著它適用于大量輸入。
[m,n] = size(mat);
for i = 1:m
j = 1;
while j <= n
seqSum = 1;
if mat(i,j) == 1
for k = j 1:n
if mat(i,k) == 1
seqSum = seqSum 1;
else
break
end
end
if seqSum < 5
mat(i,j:j seqSum-1) = 0;
end
end
j = j seqSum;
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/475412.html
標籤:matlab
上一篇:Matlab中求和的分支函式
