Reputation: 1
I'm trying to iterate through two numpy arrays of the same size, see if the difference between two elements of shared index is outside an arbitrary error range of my choosing, and then correcting that error by that same error value. However, I get an error that, to my understanding, assumes I'm trying to compare all the values of the arrays? That's not what I think I'm doing but the compiler says otherwise. I wouldn't be surprised if I am not understanding the a.all() documentation properly and there is a better way of achieving this. Here's what I have so far:
x = (b-a)*np.random.random((100,1)) + a
noise = 10*np.random.normal(size=x.shape)
y = slope*x + y_int + noise
y_true = slope*x + y_int
m = len(x)
sigma = 10
for i in range(m):
if (y[i] - y_true[i] > 0) and (abs(y[i] - y_true) >= sigma):
y[i] -=sigma
elif (y[i] - y_true[i] < 0) and (abs(y[i] - y_true) >= sigma):
y[i] += sigma
I'm thinking that maybe I could use a.any() to form boolean arrays and iterate over those elements where they are true in a nested loop, but I'm unsure of how to implement that. Any advice/guidance is appreciated. Sorry for the noobery.
Upvotes: 0
Views: 62
Reputation: 13079
This answer is mainly about an improved overall method that could be used, although below that I've added some details of what seems to be the specific bug in your code.
The loop could be avoided entirely (which is something you should always aim for when using numpy), by writing instead:
diff = y - y_true
y -= numpy.where(diff >= sigma, sigma, 0)
y += numpy.where(diff <= -sigma, sigma, 0)
Here, the inequalities and additions and subtractions are all element-by-element array operations. The numpy.where
outputs an array based on arguments of the form:
(condition, value_where_true, value_where_false)
(value_where_true and value_where_false can be arrays, but here they are scalars, which is permitted due to broadcasting, just as with the comparisons above.)
By the way, be aware that if you actually needed to represent in boolean array form the full expression that you are using in your if
statement (although I don't think you do, because it simplifies), then you would need numpy.logical_and
rather than plain and
:
numpy.logical_and(y - y_true > 0, numpy.abs(y - y_true) >= sigma)
EDIT: I think the specific error that you are getting relates to a typo inside your loop, where you have missed off the index from the final y_true
(you meant y_true[i]
), and then because any supported binary operation between an array and a scalar will broadcast the scalar across the array, the end result ends up as an array rather than your intended scalar. But you are then using and
, which does not work with arrays (see my earlier comments about logical_and
when doing element-by-element logical and), and this is what gives the error message you are seeing regarding all
when the right-hand operand of the and
is a boolean array.
Upvotes: 1