Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify numpy array section in-place using boolean indexing

Tags:

python

numpy

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]]      
like image 508
Marcus Jones Avatar asked Sep 15 '12 12:09

Marcus Jones


1 Answers

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.

like image 64
Pierre GM Avatar answered Oct 21 '22 22:10

Pierre GM