Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy division by 0 workaround

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.

like image 258
eXistanCe Avatar asked May 13 '18 16:05

eXistanCe


People also ask

How do I avoid division by zero in NumPy?

Behavior on division by zero can be changed using seterr. When both x1 and x2 are of an integer type, divide will return integers and throw away the fractional part. Moreover, division by zero always yields zero in integer arithmetic. >>> np.

How do you avoid division by zero error in Python?

The Python "ZeroDivisionError: division by zero" occurs when we try to divide a number by 0 . To solve the error, use an if statement to check if the number you are dividing by is not zero, or handle the error in a try/except block.

How do you declare a division by zero in Python?

In Python, division by zero generates the exception ZeroDivisionError: division by zero. This is because in mathematics, division by zero is undefined.

How do I divide a NumPy array by a number?

Divide NumPy Arrays With the / Operator The result is the same as the above. # creating two input arrays arr = np. array([16, 28, 33, 38, 45]) arr1 = np. array([4, 8, 13, 5, 3]) # Find the division with the / operator arr2 = arr/arr1 print(arr2) # Output : # [ 4.


1 Answers

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)
like image 57
user3483203 Avatar answered Sep 25 '22 22:09

user3483203