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
aand simply usenp.wherealongwith the invalid mask to choose between the generated random numbers anda. The implementation would be a simpler one, like so -