Reputation: 89
I want to remove all zeros from a matrix, so each row or column containing zero will be removed. Like this: the input is this matrix:
np.array([
[1, 2, 3, 4, 5],
[6, 0, 8 ,9,10],
[11,12,13,14,15],
[16, 0, 0,19,20]])
The three zeros should cause rows 1 & 3 (zero-based indexing) and columns 1 & 2 to get deleted. The output matrix shall be:
np.array([
[ 1, 4, 5],
[11,14,15]])
So far I´ve tried this:
for i in range(0,len(Matrix)):
Matrix[Matrix[:,i]!=0]
for i in range(len(Matrix),0):
Matrix[Matrix[i,:]!=0]
Upvotes: 1
Views: 82
Reputation: 353249
You could use np.ix_
to handle the indexing magic:
In [26]: arr = np.array([[1,2,3,4,5],[6,0,8,9,10],[11,12,13,14,15],[16,0,0,19,20]])
In [27]: mask = arr != 0
In [28]: arr[np.ix_(mask.all(1), mask.all(0))]
Out[28]:
array([[ 1, 4, 5],
[11, 14, 15]])
The indexing magic in question is that np.ix_
will turn the boolean arrays into the right indices for each axis:
In [29]: mask.all(1)
Out[29]: array([ True, False, True, False])
In [30]: mask.all(0)
Out[30]: array([ True, False, False, True, True])
In [31]: np.ix_(mask.all(1), mask.all(0))
Out[31]:
(array([[0],
[2]]), array([[0, 3, 4]]))
which really isn't so magical at all, it's effectively
In [34]: np.arange(len(mask.all(1)))[mask.all(1)]
Out[34]: array([0, 2])
behind the scenes.
Upvotes: 3
Reputation: 77867
The problem with your initial approach is that the first loop removes all rows with zeros. When you get to the second loop, there are no zeros remaining, and no clues about where they were, so you can't remove any columns.
in that first loop, instead of removing the row, set all non-zero entries to NaN
or some other "marker" value. Then remove every columns with a zero. Finally, come back and remove the rows with NaN
.
Upvotes: 1