2010-04-03 2 views
2

J'attribue un tableau 3D, qui contient des informations pour un certain nombre de loadcases différentes. Chaque ligne du tableau définit un cas particulier (dont il y en a 3) et j'aimerais supprimer le cas de charge (c'est-à-dire la ligne) si TOUS les éléments de la ligne (en 3D) sont égaux à zéro.Comment est-ce que je supprime une dimension de tableau où les éléments somme à zéro?

Le code je en ce moment est:

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 

À l'heure actuelle, la boucle je retirer les lignes provoque une erreur d'indexation, comme la taille des changements de matrice dans la boucle.

Quelqu'un peut-il voir une solution pour cela?

Répondre

3

Voici une alternative à la boucle, en utilisant la fonction ALL et 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

la commande matlab "any" vous indique s'il y a des éléments non nuls. Sum (Array (i,:, :) == 0) produira vrai pour certains mélanges d'éléments positifs et négatifs (par exemple [1 1 -2]) ce qui n'est probablement pas la façon de le faire. Je voudrais être intelligent et vous dire comment faire cela sans boucle for, mais le surdébit sur une boucle for est ici petit et le code est probablement plus clair si vous gardez votre boucle for. Votre erreur est cette ligne: Array(i,:,:) = [] qui provoque probablement Matlab à crier dessus d'un décalage dans le nombre d'éléments

le correctif est de garder une trace de ce que les éléments que vous souhaitez supprimer, puis prendre soin de ce au fin de la boucle

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

Si tableau est un tableau général ND vous ne voulez probablement pas à carreler un tas de toutes les commandes, de sorte que cette formulation alternative fonctionnera

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

un problème ... 'Array (i,:, :)' est en fait un tableau à trois dimensions (1 par 5 par 4 en utilisant l'exemple de la question). Vous devez donc appliquer ANY au moins deux fois: 'valid (i) = any (any (Array (i,:, :))); – gnovice

+0

Bonne prise! J'ai corrigé l'exemple et noté que vous pouvez également utiliser la forme. – Marc

+0

Vous devriez aussi pouvoir dire "valide (i) = any (Array (i, :))" – Nzbuu

Questions connexes