Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python 3.6, why does a negative number to the power of a fraction return nan when in a numpy array?

Tags:

python

numpy

I have started learning Python recently and I've been going through the NumPy official quickstart guide which includes this example for iterating.

>>> a
array([-1000,     1, -1000,    27, -1000,   125,   216,   343,   512,   
729])
>>> for i in a:
...     print(i**(1/3.))
...
nan
1.0
nan
3.0
nan
5.0
6.0
7.0
8.0
9.0

However, if I just try to raise -1000 to the power of (1/3.) outside of the loop it returns a value.

>>> -1000**(1/3.)
-9.999999999999998

With parentheses around -1000 it also returns a value.

>>> (-1000)**(1/3.)
(5+8.660254037844384j)

Why is it that the same action returns nan in the for loop? I'm using Python 3.6.3 :: Anaconda custom (64-bit). I also tried with different fractions that do not round up and it's the same. With a fraction that rounds up to .0 it works though.

I couldn't find a similar question. Excuse me if I'm missing something very obvious.

Edit: A few comments mentioned that the question duplicates NumPy, RuntimeWarning: invalid value encountered in power and it's true, the problem was I didn't see such an error. The discussion there, however, seems to include a few possible workarounds.

like image 372
Nikolay D Avatar asked Feb 28 '18 11:02

Nikolay D


People also ask

How does numpy treat NaN?

Introduction to NumPy NaN. In Python, NumPy NAN stands for not a number and is defined as a substitute for declaring value which are numerical values that are missing values in an array as NumPy is used to deal with arrays in Python and this can be initialized using numpy.

How do you power a numpy array in Python?

power() in Python. numpy. power(arr1, arr2, out = None, where = True, casting = 'same_kind', order = 'K', dtype = None) : Array element from first array is raised to the power of element from second element(all happens element-wise).

How do you replace NaN in an array?

In NumPy, to replace missing values NaN ( np. nan ) in ndarray with other numbers, use np. nan_to_num() or np. isnan() .

How do you use element-wise power in numpy?

First array elements raised to powers from second array, element-wise. Raise each base in x1 to the positionally-corresponding power in x2. x1 and x2 must be broadcastable to the same shape. An integer type raised to a negative integer power will raise a ValueError .


1 Answers

Exponentiation in python has higher precedence than the negative operator. Thus -1000**(1/3) is equivalent to -(1000**(1/3)).

When you doing this operation inside the loop you get (-1000)**(1/3). This equal to 10 * (-1**(1/3)) which a complex number. Now the array you have, uses a default data type since you did not define any that is determined according to the documentation as follows:

dtype : data-type, optional

The desired data-type for the array. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. This argument can only be used to ‘upcast’ the array. For downcasting, use the .astype(t) method.

So it is probably np.int16.

Putting all the information together, we can conclude that your array is not equipped with the appropriate dtype attribute to be able to hold the result of (-1000)**(1/3) even though the result exists.

This does not happen outside arrays since there, no dtype is assumed.


Fix \ Workaround:

>>> a = np.array([-1000, 1], dtype=np.complex)
>>> for i in a:
...     print(i**(1/3.))
...
(5+8.66025403784j)
(1+0j)
like image 60
DAle Avatar answered Sep 19 '22 06:09

DAle