我正在分配一个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循环导致索引错误,因为数组的大小在循环中发生变化。
有人能看到解决方法吗?
答案 0 :(得分:3)
以下是使用函数ALL和logical 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,:,:);