【问题标题】:How do I remove an array dimension where the elements sum to zero?如何删除元素总和为零的数组维度?
【发布时间】:2010-04-03 19:28:56
【问题描述】:

我正在分配一个 3D 数组,其中包含许多不同载荷工况的一些信息。数组中的每一行都定义了一个特定的负载情况(其中有 3 个),如果行的所有元素(3D 中)都等于零,我想删除负载情况(即行)。

我现在的代码是:

Array = zeros(3,5) %# Initialise array
Numloadcases = 3;

Array(:,:,1) = [10 10 10 10 10;
                0   0  0  0  0;
                0   0  0  0  0;]; %# Expand to a 3D array 

Array(:,:,2) = [10 10 10 10 10;
                0  0  0  0  0;
                0  0  0  0  0;];

Array(:,:,3) = [10 10 10 10 10;
                0  0  0  0  0;
                0  0  20  0  0;];

Array(:,:,4) = [10 10 10 10 10;
                0  0  0  0  0;
                0  0  20  0  0;];

%# And to remove the second row:

for i = 1:Numloadcases
  if sum(Array(i,:,:)) == 0
    Array(i,:,:) = [];
  end
end

目前,我必须删除行的 for 循环会导致索引错误,因为循环中数组的大小会发生变化。

任何人都可以看到解决此问题的方法吗?

【问题讨论】:

    标签: matlab indexing matrix


    【解决方案1】:

    这里是循环的替代方法,使用函数ALLlogical indexing

    isAllZero = all(all(Array == 0,3),2);  %# Logical index of rows with all zeroes
    Array = Array(~isAllZero,:,:);  %# Keep rows that have non-zero values
    %# Or...
    Array(isAllZero,:,:) = [];      %# Set rows with all zeroes to the empty matrix
    

    【讨论】:

      【解决方案2】:

      matlab 命令“any”告诉你是否有任何非零元素。

      sum(Array(i,:,:) == 0) 对于正负元素的某些混合(例如 [1 1 -2])会产生 true,这可能不是这样做的方法。

      我很想聪明一点,告诉你如何在没有 for 循环的情况下做到这一点,但这里 for 循环的开销很小,如果你保留 for 循环,代码可能会更清晰。你的错误是这一行: Array(i,:,:) = [] 这可能会导致 Matlab 因元素数量不匹配而对您大喊大叫

      解决方法是跟踪您要删除的元素,然后在循环结束时处理它

      valid = false([1 Numloadcases]); %preallocate
      for i = 1:Numloadcases
         valid(i) = any(any(Array(i,:,:)));
      end
      Array = Array(valid,:,:);
      

      如果 Array 是一个通用的 ND 数组,您可能不想拼凑一堆任何命令,所以这个替代公式可以工作

      valid = false([1 Numloacases]);
      for i = 1:Numloadcases
         valid(i) = any(reshape(Array(i,:,:), 1, []);
      end
      Array = Array(valid,:,:);
      

      【讨论】:

      • 一个问题...Array(i,:,:) 实际上是一个 3-D 数组(使用问题中的示例为 1×5×4)。因此,您必须至少申请 ANY 两次:valid(i) = any(any(Array(i,:,:)));.
      • 好收获!我修复了示例并指出您也可以使用 reshape。
      • 你也应该可以说“valid(i) = any(Array(i,:))”
      猜你喜欢
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      相关资源
      最近更新 更多