Retrieving non-zero blocks from a matrix
21 次查看(过去 30 天)
显示 更早的评论
Hi everyone,
I'd like to figure out a way to extract "blocks" of non-zero values from larger matrices. The following image shows an example of a matrix containing the "blocks" along the diagonal. I added the red brackets manually to better visualize the problem.
The problem I am having is that these "blocks " are not always as nice as the ones in the image above. Sometimes I get the following.
So the dimensionality of the blocks changes from matrix to matrix. Any help is greatly appreciated. Thank you
0 个评论
采纳的回答
Walter Roberson
2021-3-31
Data borrowed from @Oleg Iupikov
YourArray = [
0.3899 0 0 0 0 0
0 0.0492 0.3202 0.4881 0 0
0 0.3074 0.4613 0.7067 0 0
0 0 0 0 0.3673 0
0 0 0 0 0.9414 0
0 0 0 0 0 0.2682];
bw = logical(YourArray);
CC = bwconncomp(bw, 4); %4 connectivity... no diagonals
S = regionprops(CC,'SubarrayIdx');
chunks = arrayfun(@(s)YourArray(s.SubarrayIdx{:}), S, 'uniform', 0)
2 个评论
更多回答(1 个)
Oleg Iupikov
2021-3-31
Here is one possible solution. Please see in-line comments for explanation.
% Generate some data matrix
Data = zeros(6,6);
Data(1,1) = rand;
Data(2:3,2:4) = rand(2,3);
Data(4:5,5) = rand(2,1);
Data(6,6) = rand;
Data
% This matrix will be used to determine if we have found all the blocks.
% 1 means that this element of the matrix has not been processed yet.
FlagMat = Data>0;
% Find all blocks
SubMatCnt = 0;
while true
% Find 1st non-processed element of the matrix. It will correspond to the top-left corner of the sub-matrix.
[irow,icol] = find(FlagMat,1);
% If all elements of FlagMat are 0, we have found everything, exit the loop
if isempty(irow), break; end
% Find all neighboring non-zero elements along row
icol2 = find(~FlagMat(irow,icol:end), 1) + icol - 2; % in fact, we are finding the 1st 0-element in the row irow starting from column icol
if isempty(icol2), icol2 = size(FlagMat,2); end % it is the case when icol pointing to the last column
% Find all neighboring non-zero elements along column
irow2 = find(~FlagMat(irow:end,icol), 1) + irow - 2;
if isempty(irow2), irow2 = size(FlagMat,1); end % it is the case when irow pointing to the last row
% Form the submatrix indices
irows = irow : irow2;
icols = icol : icol2;
% Mark elements of FlagMat correspontding to the submatrix as "processed"
FlagMat(irows,icols) = false;
% Print our submatrix
SubMatCnt = SubMatCnt + 1;
fprintf('Sub-matrix %i:\n',SubMatCnt);
disp(Data(irows,icols));
end
And here is the output:
Data =
0.3899 0 0 0 0 0
0 0.0492 0.3202 0.4881 0 0
0 0.3074 0.4613 0.7067 0 0
0 0 0 0 0.3673 0
0 0 0 0 0.9414 0
0 0 0 0 0 0.2682
Sub-matrix 1:
0.3899
Sub-matrix 2:
0.0492 0.3202 0.4881
0.3074 0.4613 0.7067
Sub-matrix 3:
0.3673
0.9414
Sub-matrix 4:
0.2682
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!