2

Still trying to earn my numpy stripes: I want to perform an arithmetic operation on two numpy arrays, which is simple enough:

return 0.5 * np.sum(((array1 - array2) ** 2) / (array1 + array2))

Problem is, I need to be able to specify the condition that, if both arrays are element-wise 0 at the same element i, don't perform the operation at all--would be great just to return 0 on this one--so as not to divide by 0.

However, I have no idea how to specify this condition without resorting to the dreaded nested for-loop. Thank you in advance for your assistance.

Edit: Would also be ideal not to have to resort to a pseudocount of +1.

3 Answers 3

3

Just replace np.sum() by np.nansum():

return 0.5 * np.nansum(((array1 - array2) ** 2) / (array1 + array2))

np.nansum() treats nans as zero.

Sign up to request clarification or add additional context in comments.

Comments

3
return numpy.select([array1 == array2, array1 != array2], [0.5 * np.sum(((array1 - array2) ** 2) / (array1 + array2)), 0])

should do the trick... numpy.where might also be used.

2 Comments

This is an excellent idea (didn't know I could do this), but shouldn't it be numpy.select([array1 == 0.0 and array2 == 0.0, array1 != array2], ...) for the first condition?
Yes, I didn't catch that the first time. You can do (array1 == 0) * (array2 == 0) for the first condition. However, Sven's solution seems even better.
0

You could also try post-applying numpy.nan_to_num:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html

although I found that when I have a divide by zero in your code, it gives a warning, but fills that element with zero (when doing integer math) and NaN when using floats.

If you want to skip the sum when you have a divide by zero, you could also just do the calculation and then test for the NaN before returning:

xx = np.sum(((array1 - array2) ** 2) / (array1 + array2))
if np.isnan(xx):
    return 0
else:
    return xx 

Edit: To silence warnings you could try messing around with numpy.seterr:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.seterr.html

4 Comments

This is very good suggestion. My only complaint here is that I'd still have to silence the cascading warnings when a divide-by-zero occurs.
@Magsol: Why are there warnings? NumPy should actually divide by zero without complaining, and just yield NaN.
@Sven: I believe the warning is new as of numpy 1.5
No messing around is needed, just old_setting= np.seterr(divide= 'ignore') should be enough. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.