2016-11-11 4 views
3

Я объясню свой вопрос, используя пример. Представьте себе, что у вас есть двумерная матрица, как показано ниже:Поиск распределения длины островов в 2D-массиве?

5 4 3 8 0 0 
5 4 2 9 1 0 
5 6 2 7 2 0 
5 4 7 9 0 0 
5 6 7 1 2 0 

На островах я имею в виду группы столбцов одинаковых элементов (кроме нулей). Я хотел бы найти гистограмму длины islands, за исключением тех, которые состоят из нулевых элементов.

enter image description here

Эта матрица имеет

island-length occurrence 
    5    1 
    2    3 
    1    12 

Как я могу реализовать эту задачу с помощью Matlab?

+0

Это кажется очень сложной задачей, вы пробовали что-нибудь? – thewaywewalk

+0

Да, я попытался использовать преобразование 2D-массива в массив 1D, а затем следую http://stackoverflow.com/questions/3274043/finding-islands-of-zeros-in-a-sequence. Но у него есть недостаток в том, что он неспособен обращаться с нулями. – dexterdev

ответ

2

Может быть, есть более короткие возможности, но это будет делать - и это полностью векторизация:

A = [5 4 3 8 0 0 
    5 4 2 9 1 0 
    5 6 2 7 2 0 
    5 4 7 9 0 0 
    5 6 7 1 2 0] 

%// pad zeros to first line of A 
X(2:size(A,1)+1,:) = A; 

%// differences of X 
dX = diff(X) 

%// cumulative sum of "logicalized" differences 
cs = cumsum(logical(dX(:))) 
%// filter out zeros 
cs = cs(logical(A(:))) 
%// count occurances 
aa = accumarray(cs,1) 

%// unique occurances 
uaa = unique(aa) 
%// count unique occurances 
occ = hist(aa,uaa).' 
%// accumarray may introduce new zeros, filter out 
mask = logical(uaa) 

%// output 
out = [occ(mask) uaa(mask)] 

out = 

    12  1 
    3  2 
    1  5 
+1

@dexterdev Я сократил и упростил код, вы должны взглянуть на мое редактирование – thewaywewalk

+1

О да, я посмотрел на него. Просто здорово. Я ценю усилия. – dexterdev

1

Необходим небольшой модификации одного из моих старых фрагментах, чтобы отфильтровать нули. Здесь вы найдете:

% Your Matrix 
A = [ 5 4 3 8 0 0; 
5 4 2 9 1 0; 
5 6 2 7 2 0; 
5 4 7 9 0 0; 
5 6 7 1 2 0]; 

% Find Edges (Ends of Islands) 
B = diff(A); 
B = [ones(1,size(A,2));B~=0;ones(1,size(A,2))]; 

% At each column, find distances between island edges, filter out zero islands. 
R = cell(size(A,2),1); 
for i = 1:size(A,2) 
    [C ~] = find(B(:,i)); 
    Ac = A(C(1:end-1),i); 
    D = diff(C); 
    D(Ac==0)=[]; 
    R{i} = D; 
end 

% Find histogram of island lengths 
R = R(find(~cellfun(@isempty,R)),1); 
R = cell2mat(R); 
[a,~,c] = unique(R); 
out = [a, accumarray(c,ones(size(R)))];