【问题标题】:How can I find all the cells that have the same values in a multi-dimensional array in octave / matlab如何在 octave / matlab 的多维数组中找到具有相同值的所有单元格
【发布时间】:2015-09-24 03:26:49
【问题描述】:

如何在多维数组中找到所有具有相同值的单元格?

我可以部分使用 result=A(:,:,1)==A(:,:,2) 但我不确定如何也包含 A(:,:,3) 我尝试了 result=A(:,:,1)==A(:,:,2)==A(:,:,3) 但结果在应该有的时候返回全 0是 1 个正确答案 这是数字 8 位于数组所有页面上的同一单元格中的位置。注意:这只是一个测试,重复的数字可以被多次找到,并且是不同的数字。

PS:我使用的是 octave 3.8.1,类似于 matlab

见下面的代码:

clear all, tic
%graphics_toolkit gnuplot %use this for now it's older but allows zoom
A(:,:,1)=[1 2 3; 4 5 6; 7 9 8]; A(:,:,2)=[9 1 7; 6 5 4; 7 2 8]; A(:,:,3)=[2 4 6; 8 9 1; 3 5 8] 
[i j k]=size(A)
for ii=1:k
    maxamp(ii)=max(max(A(:,:,ii)))
    Ainv(:,:,ii)=abs(A(:,:,ii)-maxamp(ii));%the extra max will get the max value of all values in array
end

%result=A(:,:,1)==A(:,:,2)==A(:,:,3)
result=A(:,:,1)==A(:,:,2)
result=double(result); %turns  logical index into double to do find
[row col page] = find(result) %gives me the col, row, page

这是它给我的输出:

>>>A =

ans(:,:,1) =

   1   2   3
   4   5   6
   7   9   8

ans(:,:,2) =

   9   1   7
   6   5   4
   7   2   8

ans(:,:,3) =

   2   4   6
   8   9   1
   3   5   8

i =  3
j =  3
k =  3
maxamp =  9
maxamp =

   9   9

maxamp =

   9   9   9

result =

   0   0   0
   0   1   0
   1   0   1

row =

   3
   2
   3

col =

   1
   2
   3

page =

   1
   1
   1

【问题讨论】:

    标签: arrays matlab multidimensional-array octave


    【解决方案1】:

    使用bsxfun(MATLAB doc, Octave doc) 并通过调用all(MATLAB doc, Octave doc) 检查在所有切片中广播第一个切片是否相等:

    B = bsxfun(@eq, A, A(:,:,1));
    result = all(B, 3);
    

    如果我们在玩code golf,那么单线可能是:

    result = all(bsxfun(@eq, A, A(:,:,1)), 3);
    

    上述方法的美妙之处在于,您可以在第三维中拥有任意数量的切片,而不仅仅是三个。

    示例

    %// Your data
    A(:,:,1)=[1 2 3; 4 5 6; 7 9 8]; 
    A(:,:,2)=[9 1 7; 6 5 4; 7 2 8]; 
    A(:,:,3)=[2 4 6; 8 9 1; 3 5 8];
    
    B = bsxfun(@eq, A, A(:,:,1));
    result = all(B, 3);
    

    ...给我们:

    >> result
    
    result =
    
         0     0     0
         0     0     0
         0     0     1
    

    以上是有道理的,因为所有切片的第三行和第三列是每个切片共享相同值(即 8)的唯一值。

    【讨论】:

    • 这看起来不错,但你知道如果我有 2x5x7(2 行乘 5 列和 7 个维度)我该如何调整它吗?我对 3 代表我做 3x3x3 的错误有点迷茫例子。
    • 只要你有一个 3D 矩阵,这个例子应该可以工作。我不明白您所说的“7 个维度”是什么意思。你的意思是 7 个切片,每个切片是 2 x 5?我的答案或 Luis Mendo 的答案都行。
    【解决方案2】:

    这是另一种方法:沿三维计算差异并检测所有这些差异何时为零:

    result = ~any(diff(A,[],3),3);
    

    【讨论】:

    • 不错。这可能比bsxfun 占用更少的内存。
    • 这是一种优雅而优雅的方式
    • @Luis Mendo 这看起来不错,但你知道如果我有 2x5x7(2 行 x 5 列和 7 个维度)我该如何调整它吗?我对 3 代表我的错有点迷茫做 3x3x3 的例子。
    • @RickT 这两个数字3 表示“第三维”,因此对于任何 3D 数组,它应该可以在不改变任何内容的情况下工作
    • @RickT 正如我所说,不要改变那个 3。它表示第三个维度,而不是第三个维度的大小。所以:将result = ~any(diff(A,[],3),3) 用于any 3D 数组
    【解决方案3】:

    你可以的

    result = A(:,:,1) == A(:,:,2) & A(:,:,1) == A(:,:,3);
    

    【讨论】:

      【解决方案4】:

      sum 沿第三维的元素除以维数。如果值在所有维度上都相同,我们将取回原始值。否则为不同的(例如十进制)值。然后找到A和总和在第三维上相等的位置。

      all( A == sum(A,3)./size(A,3),3)
      
      ans =
      
      0   0   0
      0   0   0
      0   0   1
      

      你也可以

      all(A==repmat(sum(A,3)./size(A,3),[1 1 size(A,3)]),3)
      

      A 相比,repmat(sum(A,3)./size(A,3),[1 1 size(A,3)]) 会突出显示 this 的隐式广播。

      您完全跳过广播,只需将其与A 的第一部分进行比较

      A(:,:,1) == sum(A,3)./size(A,3)
      

      说明

      3 代表第三维。 sum(A,3) 表示我们正在对第三维求和。 然后我们将该总和除以维数。 它基本上是第三维中该位置的平均值。 如果您添加三个值,然后将其除以三,那么您将返回原始值。 例如,A(3,3,:)[8 8 8](8+8+8)/3 = 8。 如果你再举一个例子,即上面的值,A(2,3,:) = [6 4 1]。 然后(6+4+1)/3=3.667。这不等于A(2,3,:)

      sum(A,3)./size(A,3)
      ans =
      
         4.0000   2.3333   5.3333
         6.0000   6.3333   3.6667
         5.6667   5.3333   8.0000
      

      因此,我们知道元素是不一样的 贯穿整个三维。这只是我使用的一个技巧 来确定。你还必须记住 sum(A,3)./size(A,3) 原本是一个3x3x1 矩阵 将自动扩展(即广播)到 当我们与A (A == sum(A,3)./size(A,3)) 进行比较时,3x3x3 矩阵。 该比较的结果将是一个逻辑数组,其中1 用于在整个第三维中相同的位置。

      A == sum(A,3)./size(A,3)
      ans =
      
      ans(:,:,1) =
      
         0   0   0
         0   0   0
         0   0   1
      
      ans(:,:,2) =
      
         0   0   0
         1   0   0
         0   0   1
      
      ans(:,:,3) =
      
         0   0   0
         0   0   0
         0   0   1
      

      然后使用all(....,3) 获取这些。结果是3x3x1 1 表示矩阵中的值相同 第三维度。

      all( A == sum(A,3)./size(A,3),3)
      ans =
      
         0   0   0
         0   0   0
         0   0   1
      

      【讨论】:

      • 这看起来不错,但你知道如果我有 2x5x7(2 行乘 5 列和 7 个维度)如何适应它吗?我对 3 代表我做 3x3x3 示例的错误有点迷茫.
      • 我刚刚尝试了一个2x5x4 示例,它也可以。似乎对此有很多困惑,所以我添加了更多解释。我认为A(:,:,1) == sum(A,3)./size(A,3) 是最有效的。请查看更新后的帖子。希望这会有所帮助...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 2018-05-17
      • 1970-01-01
      • 2020-02-14
      相关资源
      最近更新 更多