Skip to content Skip to sidebar Skip to footer

Why Doesn't Numpy.power Act Element-wise On Arrays When The Exponent Is Negative?

What is the difference between numpy.power or ** for negative exponents and / when working with arrays? and why does numpy.power not act element-wise as described in the documentat

Solution 1:

This is primarily an issue of casting. Operators naturally assume that you do not wish to upcast a number to a different type. The closest value of 2**-1 with integers is 0, this can be verified int(2**-1) >>>0.

First create array A of type int:

A = np.arange(9).reshape(3,3)
>>> A.dtype
dtype('int64')

Copy array A to A_float as type float:

>>> A_float = A.astype(float)
>>> A_float.dtype
dtype('float64')

Run the **-1 operation on both:

>>> A_float**-1
array([[        inf,  1.        ,  0.5       ],
       [ 0.33333333,  0.25      ,  0.2       ],
       [ 0.16666667,  0.14285714,  0.125     ]])

>>> A**-1
array([[-9223372036854775808,                    1,                    0],
       [                   0,                    0,                    0],
       [                   0,                    0,                    0]])

Observe numpy does not automatically assume you want to complete this operation as float and attempts to accomplish this with integers. If you signify a float in either operand you will obtain a float output due to the "safe" casting rules:

>>> A**-1.0
array([[        inf,  1.        ,  0.5       ],
       [ 0.33333333,  0.25      ,  0.2       ],
       [ 0.16666667,  0.14285714,  0.125     ]])

Another option is to force np.power to cast the operation as a float:

>>> np.power(A,-1,dtype=float)
array([[        inf,  1.        ,  0.5       ],
       [ 0.33333333,  0.25      ,  0.2       ],
       [ 0.16666667,  0.14285714,  0.125     ]])

I am not sure why you are obtaining a float result with 1/A. 1.0/A works just fine however.


Solution 2:

** or np.power is working, but is performing integer division. Moreover, performing same operations in ipython results in RuntimeWarning of zero division.

RuntimeWarning: divide by zero encountered in true_divide

Now, we can turn same operations into float division by turning operand into float array

A = np.array([[0., 1., 2.], [3., 4., 5.], [6., 7., 8.]])

Then, 1/, ** and np.power behave identically


Post a Comment for "Why Doesn't Numpy.power Act Element-wise On Arrays When The Exponent Is Negative?"