2010-04-03 1 views
2

Я назначаю трехмерный массив, который содержит некоторую информацию для нескольких различных фреймов. Каждая строка в массиве определяет конкретный регистр загрузки (из которых 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 

В настоящее время, для цикла я должен удалить строки вызывает ошибку индексации, так как размер массива изменяется в цикле.

Может ли кто-нибудь увидеть работу вокруг этого?

ответ

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 
0

команды MATLAB «любой» говорит вам, если есть какие-либо элементы, отличные от нуля.

sum (Array (i,:, :) == 0) будет выдавать true для некоторых смесей положительных и отрицательных элементов (например, [1 1 -2]), что, вероятно, не способ сделать это.

Я хотел бы быть умным и сказать вам, как это сделать без циклов, но накладные расходы на цикл for здесь малы, и код, вероятно, более ясен, если вы держите свой цикл for. Ваша ошибка состоит эта строка: Array(i,:,:) = [] , которая, вероятно, вызывает Matlab кричать на вас о несовпадении числа элементов

исправлением является для отслеживания того, что элементы, которые вы хотите удалить, а затем позаботиться о том, что на конец петли

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

Если массив является общей ND массива вы, вероятно, не хотите плитки кучи каких-либо команд, так что эти альтернативных композиции будет работать

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

Одна проблемы ... 'Array (я,:, :)' на самом деле представляет собой 3-мерный массив (1 на 5-на-4, используя пример в вопросе). Поэтому вы должны применять ANY как минимум дважды: 'valid (i) = any (any (Array (i,:, :)));'. – gnovice

+0

Хорошая добыча! Я исправил пример и отметил, что вы также можете изменить форму. – Marc

+0

Вы также можете сказать «valid (i) = any (Array (i, :))» – Nzbuu

Смежные вопросы