Jmetzger5
Jmetzger5

Reputation: 1

I'm given a "use a.any() or a.all()" error when comparing specific elements from two numpy arrays?

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

Answers (1)

alani
alani

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

Related Questions