NumPy is a powerful scientific computing library for Python via which developers can make short work of matrix operations, random number generation, and many other complex mathematical functions. It rocks — but sometimes one runs into an error that isn’t readily understood.
In this quick breakdown, we’ll look at such a case where NumPy might produce a runtime warning indicating that an invalid value was encountered while using the true_divide function. As the error suggests, this error arises from — wait for it — using an invalid value during a division process. Most commonly, this happens when a 0 or NaN appears as the denominator.
If you try to use the
true_divide function in NumPy when there are two
0‘s present Python will generate a
RuntimeWarning. Consider the following:
# Two np.array objects b_1 = np.array([5, 6, 7, 8, 0]) b_2 = np.array([1, 2, 3, 4, 0]) # Divided using true_divide print(np.true_divide(b_1, b_2)) # Doesn't crash the program [5. 3. 2.33333333 2. nan] # But throws the following warning RuntimeWarning: divide by zero encountered in true_divide print(np.true_divide(b_1, b_2))
The solution is to address the issue of the
0‘s shown as the last element in both the
b_2 array — with the
b_2 being prioritized as it would still cause a
RuntimeWarning for dividing by zero even if the
b_1 were replaced.
Quick Intro: The true_divide Function
true_divide function is designed to make dividing collections of values such as arrays. It can be used to divide an array (a.k.a. matrix) via another array or by a single value. In either case, the operation happens element-wise.
true_divide function requires that two arrays be the same shape.
Below is a quick example of the
true_divide method being used to divide an array into another:
import numpy as np # Define some arrays a_1 = [6, 7, 8, 9, 10] a_2 = [1, 2, 3, 4, 5] # Use true_divide explicitly print(np.true_divide(a_1, a_2)) # Result [6. 3.5 2.66666667 2.25 2. ] # works with a single value as well print(np.true_divide(a_1, 3)) # Result [2. 2.33333333 2.66666667 3. 3.33333333]
NumPy also allows the implicit use of
true_divide via the
// operators when used between two NumPy arrays:
# Implicit use after converting to an array print(np.array(a_1) / np.array(a_2)) # Result [6. 3.5 2.66666667 2.25 2. ] # Implicit use after converting to an array, # and using static value print(np.array(a_1) / 3) # Result [2. 2.33333333 2.66666667 3. 3.33333333] # Use of floor division print(np.array(a_1) // np.array(a_2)) # Result [6 3 2 2 2] # Use of floor division with single value # Use of floor division print(np.array(a_1) // 3) # Result [2 2 2 3 3]
However, should one try to use these types of syntaxes with non-np arrays one will receive an error:
# Divide two lists print(a_1 // a_2) TypeError: unsupported operand type(s) for //: 'list' and 'list'
The closest pure-Python analog to the
true_divide function would be a custom list comprehension as such:
# Elementwise division of two lists vals = [x / a_2[i] for i, x in enumerate(a_1)] print(vals) # Result [6.0, 3.5, 2.6666666666666665, 2.25, 2.0] # Elementwise division of two lists, using floor division vals = [x // a_2[i] for i, x in enumerate(a_1)] print(vals) # Result [6, 3, 2, 2, 2]
While convenient to stay in the syntax of Python — and avoid a dependency — this syntax becomes clunky and unclear if used often. Now that we have an idea of how collections can be multiplied with or without NumPy, let’s consider some issues that may arise when using NumPy specifically.
The Issue: Invalid Value Encountered in true_divide
true_divide function, much like most division functions, does not accommodate the division via
NaN, or otherwise zero-ish values. Below we’ll create two NumPy arrays, each with a value of
0 included and attempt the
# Create 2 np.array objects b_1 = np.array([5, 6, 7, 8, 0]) b_2 = np.array([1, 2, 3, 4, 0]) # do an explicit true_divide print(np.true_divide(b_1, b_2)) # Result [5. 3. 2.33333333 2. nan] RuntimeWarning: invalid value encountered in true_divide print(np.true_divide(b_1, b_2))
First off it’s important to note this isn’t an
Exception but rather a
Warning — a
RuntimeWarning to be exact. This won’t’ cause a program to crash but will result in an
NaN value in the resulting array. The fix is to remove the zeroes.
Another Issue: Divide by Zero Encountered in true_divide
0 in the first array will sidestep the
RuntimeWarning issue regarding the invalid value but will present another
RuntimeWarning issue: dividing by zero. Consider the following code:
# Create 2 np.array objects b_1 = np.array([5, 6, 7, 8, 1]) b_2 = np.array([1, 2, 3, 4, 0]) # do an explicit true_divide print(np.true_divide(b_1, b_2)) # Result [5. 3. 2.33333333 2. inf] RuntimeWarning: divide by zero encountered in true_divide print(np.true_divide(b_1, b_2))
Note here the return value consists of an
np.array object in which the last element is the value
inf representing infinity. This might be desired behavior depending on one’s application hence the issuance of a
Warning rather than an
NumPy is a powerful library and is an under-the-hood dependency of many of the most popular data science libraries like Pandas, Sci-kit Learn, and even Machine learning libraries like Tensor Flow. It can supercharge matrix-based calculations and provides enough convenience functions to write books about.
The odd behavior noted here comes from very contrived, intentional examples. In many cases, these errors may arise when a
NaN value is unknowingly present in an array. For example, perhaps such a value results after a first calculation such that the
RuntimeWarning is generated during the second — hard to check for that beforehand!