How to remove zeros from an array?
Show older comments
I want to remove zeroes from an array. The array has exactly one zero per row. For example: a = [1 4 0 3; 0 1 5 5; 1 0 8 1; 5 4 4 0; 0 1 5 2] Should be turned into a = [1 4 3; 1 5 5; 1 8 1; 5 4 4; 1 5 2] I have tried using the command a(a==0) = []; However, this turns the 2000x50 array into an 1x98000 array instead of an 2000x49 array like I want it. Any ideas?
Accepted Answer
More Answers (2)
saber kazemi
on 12 Dec 2018
1 vote
If we do not know how much of the elements to submit after we remove the zero elements.
a = [is a big matrix]
v = nonzeros(a');
newmat = reshape(v,?,?)'
Any ideas?
6 Comments
ytzhak goussha
on 16 Dec 2018
Edited: ytzhak goussha
on 16 Dec 2018
I have been working on this problme for the some time now,
so far the solution that i have reached works better if you know for certain that the number of zeros in each row is the same, if not, then it must be converted to a cell class.
a=matrix %a big matrix with unknown number of zeroes
[sz1,sz2]=size(a);
new_sz2=zeros(1,sz1) %This array will hold the size of each row after removing zeros
for i=1:sz1
new_mat{i}= nonzeros(a(i,:));
new_row_sz(i)=size(new_mat{i},1)
end
if range(new_row_sz) == 0
new_mat=cell2mat(new_mat);
end
Farshad Bolouri
on 8 Nov 2020
This is how I have solved this problem:
Z = find(~a);
[x,~] = ind2sub(size(a),Z);
a(x,:) = [];
This worked for my application. Please me know if it also works for you. It is possible to tweek it for different applications.
Daniel Boateng
on 26 Feb 2021
It helped me. Thanks Farshad.
Patrick Benz
on 6 Oct 2021
Edited: Patrick Benz
on 6 Oct 2021
Both methods don't seem to work for me.
I have an 22762 x 20 double array which contains 19488 zeros. The problem is that I don't know how many zeros are in each row and the second problem is that they aren't equally distributed.
A (1:10)
4707 0 0 5178 947 0 0 1417 0 0 0 2506 0 0 0 2974 2037 0 0 3442
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
963 0 0 1433 4693 0 0 5164 0 0 0 6258 0 0 0 6729 5787 0 0 7200
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4708 0 0 5179 948 0 0 1418 0 0 0 2509 0 0 0 2977 2040 0 0 3445
A (1287:1293)
0 0 614 1084 0 0 1555 2023 0 0 4186 0 0 0 7009 0 0 0 6538 7480
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 3893 3427 0 0 4830 4361 0 0 2785 0 0 0 5598 0 0 0 6069 5127
The uneven spacing for is to show the irregularities.
Is there any chance that I can remove the zeros from the matrix without "loosing" the form for the nonzero elements? so that it would be something like this?
A(1)
4707 5178 947 1417 2506 2974 2037 3442
963 1433 4693 5164 6258 6729 5787 7200
When I try to use cell2mat I get an error
Error using cat
Dimensions of arrays being concatenated are not consistent.
Error in cell2mat (line 75)
m{n} = cat(2,c{n,:});
But to be honest, I never worked with cells until now so I don't really know what the error means.
"Both methods don't seem to work for me."
Neither method is suitable for your data. Both methods are fragile and should be avoided.
The simplest approach is to detect the values that you want to remove and then use ANY with its dimension argument (or whatever logic you need for your task) to create a logical index vector of the rows that you need to remove. Then use that logical index to remove the rows.
For example:
A = randi([0,3],7,4)
X = any(A==0,2)
A(X,:) = []
Patrick Benz
on 6 Oct 2021
Edited: Patrick Benz
on 6 Oct 2021
Das scheint zumindest schon einmal für die Reihen zu funktionieren, welche nur 0 Elemente enthalten.
Bei den gemischten Reihen funktioniert es aber offensichtlich nicht, da nur die Reihen von A behalten werden, welche keine 0 enthalten.
Wenn ich den Code so auf meine Matrix anwende, bekomme ich einen 0 x 20 double als Ergebnis.
Wäre es einfacher, wenn ich wüsste, wie viele 0 pro Reihe in der Matrix enthalten sind?
Edit:
Auch wenn es sicherlich nicht das schnellste oder eleganteste Ergebnis ist, habe ich es mit geschachtelten Schleifen geschafft.
Elementset_Nodes = 22762 x 21 double
Node_Coord = 7765 x 1 double
r=1;
[LIA, LOCB]=ismember(Elementset_Nodes(:,2:end),Node_Coord(:,1));
for i=1:length(LOCB)
X=0;
X=find(LOCB(i,:));
if sum(X)~=0
for j=1:length(X)
new_Mat(r,1)=Elementset_Nodes(i,1);
new_Mat(r,j+1)=LOCB(i,X(j));
end
else
new_Mat(r,:)=0;
new_Mat(r,:)=[];
end
[r, c]=find(new_Mat);
r=max(r)+1;
end
Elementset_Nodes=horzcat(Elementset_Nodes(:,1),new_Mat);
Mathieu PEYRE
on 2 Aug 2022
Edited: Mathieu PEYRE
on 2 Aug 2022
Hello,
Rather than remove the zeros of your matrix, you can create an other matrix with the non zeros rows in it.
EXEMPLE: A=[ 1 2 3; 0 0 0; 3 4 5; 0 1 0] and you want B=[1 2 3; 3 4 5; 0 1 0]
(If you want to remove all rows with at least one zero and obtain B=[1 2 3; 3 4 5], you can replace the "||" by "&&" in the "if" condition)
L=1;
for i=1:length(A)
if A(i,1)~=0 || A(i,2)~=0 || A(i,3)~=0
B(L,:)=A(i,:);
L=L+1;
end
end
Categories
Find more on Contour Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!