在3D数组

时间:2015-12-01 11:39:13

标签: arrays matlab matrix difference

假设我有一个大小为100x150x30的数组,一个地理网格100x150,每个网格点有30个值,并希望沿着第三维找到连续的元素,其最小长度为3。

我想找到连续元素块的最大长度,以及出现次数。

我在一个简单的向量上试过这个:

var=[20 21 50 70 90 91 92 93];
a=diff(var);

q = diff([0 a 0] == 1);
v = find(q == -1) - find(q == 1);

v = v+1;
v2 = v(v>3);
v3 = max(v2); % maximum length: 4
z = numel(v2); % number: 1

现在我想将它应用到我的数组的第三维。

A是我的100x150x30数组,我走得很远:

aa = diff(A, 1, 3);

b1 = diff((aa == 1),1,3);
b2 = zeros(100,150,1);

qq = cat(3,b2,b1,b2);

但是我坚持下一步,即:find(qq == -1) - find(qq == 1);。我无法使它发挥作用。

有没有办法把它放在循环中,还是我必须以另一种方式找到连续值?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

A = randi(25,100,150,30); %// generate random array
tmpsize = size(A); %// get its size
B = diff(A,1,3); %// difference
v3 = zeros(tmpsize([1 2])); %//initialise
z = zeros(tmpsize([1 2]));
for ii = 1:100 %// double loop over all entries
    for jj = 1:150
        q = diff([0 squeeze(B(ii,jj,:)).' 0] == 1);%'//
        v = find(q == -1) - find(q == 1);
        v=v+1;
        v2=v(v>3);
        try %// if v2 is empty, set to nan
        v3(ii,jj)=max(v2);
        catch
            v3(ii,jj)=nan;
        end
        z(ii,jj)=numel(v2);
    end
end

上述似乎有效。它只是在你希望获得差异的两个维度上进行双重循环。

我认为您遇到困难的部分是使用squeeze将变量放入变量q

try/catch仅用于防止v2中的空连续数组在v3的赋值中抛出错误,因为这将删除其条目。现在它只是将其设置为nan,但您当然可以将其切换为0

答案 1 :(得分:2)

这是一种矢量化方法 -

%// Parameters
[m,n,r] = size(var);
max_occ_thresh = 2        %// Threshold for consecutive occurrences

% Get indices of start and stop of consecutive number islands
df = diff(var,[],3)==1;   
A = reshape(df,[],size(df,3));
dfA = diff([zeros(size(A,1),1) A zeros(size(A,1),1)],[],2).'; %//'
[R1,C1] = find(dfA==1);
[R2,C2] = find(dfA==-1);

%// Get interval lengths
interval_lens = R2 - R1+1;

%// Get max consecutive occurrences across dim-3
max_len = zeros(m,n);
maxIDs = accumarray(C1,interval_lens,[],@max);
max_len(1:numel(maxIDs)) = maxIDs

%// Get number of consecutive occurrences that are a bove max_occ_thresh
num_occ = zeros(m,n);
counts = accumarray(C1,interval_lens>max_occ_thresh);
num_occ(1:numel(counts)) = counts

示例运行 -

var(:,:,1) =
     2     3     1     4     1
     1     4     1     5     2
var(:,:,2) =
     2     2     3     1     2
     1     3     5     1     4
var(:,:,3) =
     5     2     4     1     2
     1     5     1     5     1
var(:,:,4) =
     3     5     5     1     5
     5     1     3     4     3
var(:,:,5) =
     5     5     4     4     4
     3     4     5     2     2
var(:,:,6) =
     3     4     4     5     3
     2     5     4     2     2
max_occ_thresh =
     2
max_len =
     0     0     3     2     2
     0     2     0     0     0
num_occ =
     0     0     1     0     0
     0     0     0     0     0