仅在第三维的3D逻辑数组中使用Matlab“查找” [英] Using Matlab 'find' in a 3D logical array along the 3rd dimension only

查看:249
本文介绍了仅在第三维的3D逻辑数组中使用Matlab“查找”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如:

  A = randi([0 1],x,y, Z); 

其中x,y,z是整数。

有没有办法找到第一个真正的价值沿着第三维'z',为每个(x,y)?

我可以在一个循环如下:

  B = zeros(x,y); 

for ix = 1:x
for iy = 1:y
B(ix,iy)= find(A(ix,iy,:),1,'first );
end
end

是否有数组操作可以让我做它没有一个循环?

解决方案

不是一个非常简单的。



这是因为在第三维的任何地方都不可能有。顺便说一句,你正在做的事情可能导致一个非常难找到的错误。如果在某个地方没有真值, find 将返回空矩阵( [] )。而且,在MATLAB中为空分配一个空矩阵将从要分配的数组中删除 元素。

含义:
$ b $ ol

  • B(ix,iy )将被删除

  • B 中元素的数目会缩减1

  • 所有后续结果将分配到 B

  • 中的错误位置当您到达结尾 A (因此现在索引超出 B 的边界),MATLAB会自动增长数组 B 以适应您的任务。

  • 你不会更聪明,但所有的结果都是毫无意义的垃圾。幸运的是,如果你在维度大于1的数组上进行操作,MATLAB会发出警告, BUT ,如果你对向量使用相同的技术(例如, B 是一个向量),MATLAB不会警告你。因此,至少要做一个检查:

    pre $

    对于ix = 1:x
    对于iy = 1:y
    如果有的话(A(ix,iy,:))
    B(ix,iy)= find(A(ix,iy ,:),1,'first');
    end
    end
    end

    另请注意,任何都可以取第二个参数指定维度为任意结束,意思是

      any(A,3)

    将会返回一个 x×y 逻辑数组,其中包含 true ,如果存在 true 放在 A 沿着它的第三维,否则 false 。这可以帮助你避免显式计算索引(通常情况下,如果你改变了范式,它们并不是真正需要的)。

    现在,说了这么多,你可以用

    pre $ 〜,B] = max(A〜= 0,[],3);

    但是您仍然必须对全零进行检查:

      B(〜any(A,3))= 0; 

    我会说,循环与检查只是 so 多更直观,它会有我的偏好。然而, max 技术快了大约7倍,所以当正确记录时(可能将循环作为上面注释的一部分,以及随附的单元测试)那么好吧,为什么不呢。

    I have a 3D logical array, for example:

    A = randi([0 1],x,y,z);
    

    where x,y,z are integers.

    Is there a way to find the first true value along the 3rd dimension 'z', for each (x,y)?

    I can do it in a loop like this:

    B = zeros(x,y);
    
    for ix = 1:x
        for iy = 1:y
            B(ix,iy) = find(A(ix,iy,:),1,'first');
        end
    end
    

    Is there an array operation which will allow me to do it without a loop?

    解决方案

    Not a very straightforward one.

    That is because there may not be a true anywhere along the third dimension.

    By the way, what you're doing may lead to an extremely hard to find bug. If it is the case that there is no true value somewhere, find will return the empty matrix ([]). And, assigning an empty matrix to something in MATLAB will delete that element from the array you're assigning to.

    Meaning:

    1. B(ix,iy) will be deleted
    2. The number of elements in your B will shrink by 1
    3. All subsequent results will be assigned to the wrong positions in B
    4. When you've reached the end of A (and are thus now indexing beyond the boundary of B), MATLAB will automatically grow the array B to fit your assignment.

    You'll be none the wiser, but all the results are meaningless garbage.

    Luckily, MATLAB throws a warning if you're doing that on arrays with dimension larger than 1, BUT, if you're using the same technique on vectors (e.g., B is a vector), MATLAB will not warn you.

    So, at the very least, do a check:

    for ix = 1:x
        for iy = 1:y
            if any(A(ix,iy,:))
                B(ix,iy) = find(A(ix,iy,:), 1, 'first'); 
            end
        end
    end
    

    Also note that any can take a second argument specifying the dimension to "any" over, meaning

    any(A,3)
    

    will return an x×y array of logicals, containing true if there is a true in A along its third dimension, and false otherwise. This may help you prevent having to compute the indices explicitly (oftentimes, they are not really explicitly needed if you change paradigm).

    Now, having said all that, you could use

    [~, B] = max(A ~= 0, [], 3);
    

    but you'd still have to do checks on all-zeros:

    B(~any(A, 3)) = 0;
    

    I'd say, the loop with the check is just so much more intuitive that it'd have my preference. However, the max technique is about 7 times faster, so when properly documented (probably with the loop as part of the comment above it, as well as in an accompanying unit test), then well, why not.

    这篇关于仅在第三维的3D逻辑数组中使用Matlab“查找”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆