python numpy数组中负数的立方根返回nan

5cg8jx4n  于 2022-12-10  发布在  Python
关注(0)|答案(3)|浏览(133)

来自Numpy文档:

>>> 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

有人能给我解释一下最后一行代码吗?i to the power of 1/3如何等于这些数字?
例如-1000^1/3 = nan?我跳过了什么部分?

yeotifhr

yeotifhr1#

在numpy中有一个内置的函数来查找cuberoot。看看这个:

print(np.cbrt(a))

您的输出将为:

[-10.   1. -10.   3. -10.   5.   6.   7.   8.   9.]
muk1a3rh

muk1a3rh2#

在Python中,(-1000)**(1/3.)返回复数,

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

发生这种情况是因为计算机存储数字的方式,1/3 = 0.33333...是一个无理数,在某个点得到近似,因此有精度损失

>>> 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

这里ndarray a中的值是numpy.int32类型。
代码(i)**(1/3.)返回numpy.float64类型的结果,因为第二个参数是浮点。

>>> [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.)是复数,不能存储为numpy.float64,因此nan
为了避免出现nan,您可以将ndarraydtype更改为numpy.complex并进行计算

>>> 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)

您可以使用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
mefy6pfw

mefy6pfw3#

i to the power of 1/3如何等于这些数字?
这不仅仅是NumPy或Python特有的特性,它来自数学。(在你的例子中,它是通过覆盖__pow__来处理数学而不是Python,但它也可以处理纯Python的数字。)

>>> 2 ** 5  # 2 raised to 5
32
>>> 32 ** (1/5)  # 5th root of 32
2.0

x**y(或“x自乘到y”),“y”可以是:

  • x**2:“x的平方”
  • x**3:“x的立方”
  • x**5:“x的5次方”或“x的5次方”

它也可以是分数:

  • x**(1/2):“x的平方根”
  • x**(1/3):* “x的立方根”*
  • x**(1/5):* “x的五次方根”*

下面是一个source which explains it better
Sqrt进程实际上撤消了2的幂次运算所做的操作;换句话说,在某种意义上,这是平方的“相反”过程。2回想一下我们的代数规则,一个数的幂可以再次提升到一个幂,我们所做的只是乘幂;那么请注意,平方根过程可以写成1/2次方:
平方(2平方)=(2平方)½ = 2平方× ½ = 2
还有一个更数学化的证明:Why Is an Exponent of 1/2 the Same as a Square Root?

相关问题