如何删除元素总和为零的数组维度?

时间:2010-04-03 19:28:56

标签: matlab indexing matrix

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

我目前的代码是:

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循环导致索引错误,因为数组的大小在循环中发生变化。

有人能看到解决方法吗?

2 个答案:

答案 0 :(得分:3)

以下是使用函数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

答案 1 :(得分:0)

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

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

我很想聪明并且告诉你如何使用no 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,:,:);