Reputation: 735
lets say I have two arrays
x = [1,2,3]
y = [0,1,0]
I need to divide the arrays element-wise, thus using numpy. My issue is the "secure division" implemented. when doing:
np.divide(x,y).tolist()
I get the output:
[0.0, 2.0, 0.0]
My problem with this is that I need it to return the element that is not 0 when it divides by 0, making the ideal output:
[1.0, 2.0, 3.0]
Is there any workaround to do this using numpy? Manually defining a function to do this, is there any optimized way to do this, without making a custom divide function (like the following) and using it on every pair of elements?
def mydiv(x, y):
if y == 0:
return x
else:
return x / y
NOTE: the reason Im worried about optimization is that this will run in the cloud, so resources are limited, and when having 300+ element arrays, doing this does not seem optimal at all.
Upvotes: 5
Views: 914
Reputation: 51165
A simple trick you can use:
x / (y + (y==0))
In action:
x = np.array([1, 5, 3, 7])
y = np.array([0, 2, 0, 4])
print(x / (y + (y==0)))
# [1. 2.5 3. 1.75]
Timings:
def chrisz(x, y):
return x/(y+(y==0))
def coldspeed1(x, y):
m = y != 0
x[m] /= y[m]
return x
def coldspeed2(x, y):
m = ~(y == 0)
x[m] /= y[m]
return x
def coldspeed3(x, y):
m = np.flatnonzero(y)
x[m] /= y[m]
return x
Results:
In [33]: x = np.random.randint(10, size=10000).astype(float)
In [34]: y = np.random.randint(3, size=10000).astype(float)
In [35]: %timeit chrisz(x, y)
29.4 µs ± 601 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [36]: %timeit coldspeed1(x, y)
173 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [37]: %timeit coldspeed2(x, y)
184 µs ± 1.36 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [38]: %timeit coldspeed3(x, y)
179 µs ± 2.68 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Upvotes: 5
Reputation: 402263
The easiest/fastest way to do this would be to just divide the values corresponding to a non-zero y-val.
x = [1, 2, 3]
y = [0, 1, 0]
x, y = [np.array(arr, dtype=float) for arr in (x, y)]
m = y != 0 # ~(y == 0) # np.flatnonzero(y)
x[m] /= y[m]
print(x)
array([1., 2., 3.])
Upvotes: 4