Reputation: 970
Given a 2D numpy array, i.e.;
import numpy as np
data = np.array([
[11,12,13],
[21,22,23],
[31,32,33],
[41,42,43],
])
I need modify in place a sub-array based on two masking vectors for the desired rows and columns;
rows = np.array([False, False, True, True], dtype=bool)
cols = np.array([True, True, False], dtype=bool)
Such that i.e.;
print data
#[[11,12,13],
# [21,22,23],
# [0,0,33],
# [0,0,43]]
Upvotes: 12
Views: 4353
Reputation: 20339
Now that you know how to access the rows/cols you want, just assigne the value you want to your subarray. It's a tad trickier, though:
mask = rows[:,None]*cols[None,:]
data[mask] = 0
The reason is that when we access the subarray as data[rows][:,cols]
(as illustrated in your previous question, we're taking a view of a view, and some references to the original data get lost in the way.
Instead, here we construct a 2D boolean array by broadcasting your two 1D arrays rows
and cols
one with the other. Your mask
array has now the shape (len(rows),len(cols)
. We can use mask
to directly access the original items of data
, and we set them to a new value. Note that when you do data[mask]
, you get a 1D array, which was not the answer you wanted in your previous question.
To construct the mask, we could have used the &
operator instead of *
(because we're dealing with boolean arrays), or the simpler np.outer
function:
mask = np.outer(rows,cols)
Edit: props to @Marcus Jones for the np.outer
solution.
Upvotes: 11