沿着第三维使用find

时间:2017-09-23 10:42:40

标签: matlab vectorization

我有一个2 * 3 * 3矩阵print("foo")

a

将第三维视为深度值。我想找到a=[1 1 1;1 1 1]; a(:,:,2)=[1 1 1;1 1 1]+1; a(:,:,3)=[1 1 1;1 1 1]+2; 大于2的深度。在这种情况下,结果应为:

a

有没有办法以矢量化的方式做到这一点?

我的尝试

我尝试了以下但是它不太有效:

[3 3 3;3 3 3]

在这种情况下有效,但这是一个幸运的案例。

如果我使用:

inds=find(a>2) %find indices of elements>2  
lev=ceil(inds/2/3) %divide by the size of each layer. it returns the layer indices on which the an element>2 is

depths = reshape(lev,2,3) 

inds =

    13
    14
    15
    16
    17
    18


lev =

     3
     3
     3
     3
     3
     3

depths =

     3     3     3
     3     3     3

现在它无法工作,因为沿着最后一列,我有多个大于2的值。确实:

a=[1 1 1;1 1 2];
a(:,:,2)=[1 1 1;1 1 2]+1;
a(:,:,3)=[1 1 1;1 1 2]+2;
  

使用重塑时出错       要重新修复元素的数量,不得更改。

我看不到解决方法。

我还尝试将inds=find(a>2) %find indices of elements>2 lev=ceil(inds/2/3) %divide by the size of each layer. it returns the layer indices on which the an element>2 is depths = reshape(lev,2,3) inds = 12 13 14 15 16 17 18 lev = 2 3 3 3 3 3 3 inds = 12 13 14 15 16 17 18 lev = 2 3 3 3 3 3 3 与'first'选项一起使用但完全没有成功。

3 个答案:

答案 0 :(得分:4)

您可以使用[~,idx]=max(a>2,[],3); 功能的第二个输出:

           <local:TimerView x:Name="timerView">
                <local:TimerView.ProgressBar>
                    <BoxView BackgroundColor="Maroon" />
                </local:TimerView.ProgressBar>
                <local:TimerView.TrackBar>
                    <BoxView BackgroundColor="Gray" />
                </local:TimerView.TrackBar>
            </local:TimerView>
            <!--<Grid x:Name="a">
                <local:TimerView x:Name="timerView1" VerticalOptions="FillAndExpand">
                    <local:TimerView.ProgressBar>
                        <Frame HasShadow="false" Padding="0" Margin="0" BackgroundColor="#AAAAAA" CornerRadius="0" VerticalOptions="FillAndExpand" />
                    </local:TimerView.ProgressBar>
                    <local:TimerView.TrackBar>
                        <Frame HasShadow="false" Padding="0" Margin="0" CornerRadius="0" BackgroundColor="#EEEEEE" VerticalOptions="FillAndExpand" />
                    </local:TimerView.TrackBar>
                </local:TimerView>
            </Grid>
            <Grid x:Name="b">
                <local:TimerView x:Name="timerView2" VerticalOptions="FillAndExpand">
                    <local:TimerView.ProgressBar>
                        <Frame HasShadow="false" Padding="0" Margin="0" BackgroundColor="#AAAAAA" CornerRadius="0" VerticalOptions="FillAndExpand" />
                    </local:TimerView.ProgressBar>
                    <local:TimerView.TrackBar>
                        <Frame HasShadow="false" Padding="0" Margin="0" CornerRadius="0" BackgroundColor="#EEEEEE" VerticalOptions="FillAndExpand" />
                    </local:TimerView.TrackBar>
                </local:TimerView>
            </Grid>-->

答案 1 :(得分:1)

找到值大于2的逻辑索引,然后将其转换为double,以便0 {s}可以替换为NaN s。添加常量以表示3D切片的数量。然后最后使用min来查找第三维中忽略NaN s的最小值。

depth = double(a>2);  %Finding logical indices where values > 2 and converting to double
depth(depth==0)=NaN;  %Replacing zeros with NaNs
depth=bsxfun(@plus,depth,reshape(0:2,1,1,[])); %Adding const representing # of 3D slice
%If you have R2016b or later, you can use implicit expansion i.e
%                depth=depth+reshape(0:2,1,1,[]);  instead of the last step
depth=min(depth,[],3);%Finding the minimum value along the third dimension

答案 2 :(得分:1)

做一些数学我想出了这个单线:

1 + size(a, 3)*ones(size(a, 1), size(a, 2)) - sum(a > 2, 3)

测试案例1:

>> a=[1 1 1;1 1 1];
a(:,:,2)=[1 1 1;1 1 1]+1;
a(:,:,3)=[1 1 1;1 1 1]+2;

>> 1 + size(a, 3)*ones(size(a, 1), size(a, 2)) - sum(a > 2, 3)

ans =

     3     3     3
     3     3     3

测试案例2:

>> a=[1 1 1;1 1 2];
a(:,:,2)=[1 1 1;1 1 2]+1;
a(:,:,3)=[1 1 1;1 1 2]+2;

>> 1 + size(a, 3)*ones(size(a, 1), size(a, 2)) - sum(a > 2, 3)

ans =

     3     3     3
     3     3     2