Reputation: 429
From Numpy documentation:
>>> a = np.arange(10)**3
>>> a
array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000 # equivalent to a[0:6:2] = -1000; from start to position 6, exclusive, set every 2nd element to -1000
>>> a
array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729])
>>> a[ : :-1] # reversed a
array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000])
>>> 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
Could somebody explain me the last line of code? How does i to the power of 1/3
equal these numbers?
For example -1000^1/3 = nan
? What part have I skipped over?
Upvotes: 2
Views: 3011
Reputation: 15962
How does
i to the power of 1/3
equal these numbers?
This is not just a NumPy or Python-specific feature. It's from math. (In your example, it's numpy handling the math instead of Python, by overriding __pow__
but it works with pure-Python numbers as well.)
>>> 2 ** 5 # 2 raised to 5
32
>>> 32 ** (1/5) # 5th root of 32
2.0
x ** y (or "x raised to y"), 'y' can be:
It can also be a fraction:
Here's a source which explains it better:
the Sqrt process actually undoes what the raising to the power of 2 had done; in other words, in some sense this is the "opposite" process of squaring. Recall from our algebraic rules for powers that a number to a power can be raised to a power again and all we do is multiply the powers; then note that the square root process can be written as raising to the power of ½:
Sqrt(2²) = (2²)½ = 2² × ½ = 2^1 = 2
And for a more mathematical proof: Why Is an Exponent of 1/2 the Same as a Square Root?
Upvotes: 0
Reputation: 1012
In Python, (-1000)**(1/3.)
returns a complex number,
>>> (-1000)**(1/3.)
(5+8.660254037844384j)
This happens because the way computer store numbers, 1/3 = 0.33333...
is an irrational number which at some point gets approximated and therefore there is a loss in precision
>>> a = np.arange(10)**3
>>> a[:6:2] = -1000
>>> a
array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512,
729], dtype=int32)
>>> for i in a:
print((i)**(1/3.))
nan
1.0
nan
3.0
nan
4.999999999999999
5.999999999999999
6.999999999999999
7.999999999999999
8.999999999999998
Here the values in the ndarray a
are of numpy.int32
type.
The code (i)**(1/3.)
returns a result of type numpy.float64
since the second argument is a floating point.
>>> [type((i)**(1/3.)) for i in a]
[<class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>, <class 'numpy.float64'>]
(-1000)**(1/3.)
is a complex number and cannot be stored as as numpy.float64
therefore nan
To avoid the nan
you can change the dtype
of the ndarray
to numpy.complex
and do the calculations
>>> b = a.astype(np.complex)
>>> b
array([-1000.+0.j, 1.+0.j, -1000.+0.j, 27.+0.j, -1000.+0.j,
125.+0.j, 216.+0.j, 343.+0.j, 512.+0.j, 729.+0.j])
>>> for i in b:
print((i)**(1/3.))
(4.999999999999999+8.660254037844384j)
(1+0j)
(4.999999999999999+8.660254037844384j)
(3+0j)
(4.999999999999999+8.660254037844384j)
(4.999999999999999+0j)
(5.999999999999999+0j)
(6.999999999999999+0j)
(7.999999999999999+0j)
(8.999999999999998+0j)
You can take the absolute values of these numbers using abs()
>>> for i in b:
print(round(abs((i)**(1/3.))))
10.0
1.0
10.0
3.0
10.0
5.0
6.0
7.0
8.0
9.0
Upvotes: 3
Reputation: 518
There is inbuilt function in numpy to find cuberoot. Check this out:
print(np.cbrt(a))
Your output will be :
[-10. 1. -10. 3. -10. 5. 6. 7. 8. 9.]
Upvotes: 6