I have an array of the form
a = np.array([[1,2],[3,4],[5,6]])
and I have a "domain" or boundary, which is again an array of the form
b = np.array([[0, 4], [3,7]])
Basically I want to check that a[:,0]
is within the first row of b
and that a[:,1]
is within the second row of b
. For instance in this example a[:,0]=[1,3,5]
and we can see that they all work, except for 5 that is bigger than 4. Similarly a[:,1] = [2,4,6]
and so we see that 2 fails because 2<3.
So basically I want 0 <= a[:,0] <= 4
and 3 <= a[:,1]<=7
. When a number goes out of this boundaries, I want to basically replace it with a random number within the boundary.
My try
a[:,0][~np.logical_and(b[0][0] <= a[:,0], a[:,0] <= b[0][1])] = np.random.uniform(b[0][0], b[0][1])
a[:,1][~np.logical_and(b[1][0] <= a[:,1], a[:,1] <= b[1][1])] = np.random.uniform(b[1][0], b[1][1])
Is there a faster/better way?
Approach #1 : Here's one approach -
Sample run -
Approach #2 : Another approach would be to generate scaled and offsetted random numbers of the same shape as
a
and simply usenp.where
alongwith the invalid mask to choose between the generated random numbers anda
. The implementation would be a simpler one, like so -