Кубический корень из отрицательных чисел в массиве NumPy возвращает Nan - PullRequest
0 голосов
/ 22 октября 2018

Из документации 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?Какую часть я пропустил?

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Как i to the power of 1/3 равняется этим числам?

Это не просто особенность NumPy или Python.Это из математики. (В вашем примере это бесполезная обработка математики вместо Python путем переопределения __pow__, но она работает и с числами чистого 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 в квадрате»
  • х ** 3: "х куб"
  • х ** 5: "х повышен до 5" или "5-я степень х"

Это также может быть дробь:

  • x ** (1/2): "квадратный корень из x"
  • x** (1/3): "кубический корень из x"
  • x ** (1/5): "5-й корень из x"

Вот источник , который объясняет это лучше :

процесс Sqrt фактически отменяет то, что сделал повышение до степени 2;другими словами, в некотором смысле это «противоположный» процесс возведения в квадрат.Напомним из наших алгебраических правил для степеней, что число до степени снова может быть возведено в степень, и все, что мы делаем, это умножаем эти степени;затем обратите внимание, что процесс квадратного корня можно записать как возведение в степень ½:

Sqrt (2²) = (2²) ½ = 2² × ½ = 2 ^ 1 = 2

И для более математического доказательства: Почему показатель 1/2 равен квадратному корню?

0 голосов
/ 22 октября 2018

В 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Вы можете изменить dtype из ndarray на 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
0 голосов
/ 22 октября 2018

В numpy есть встроенная функция для поиска cuberoot.Проверьте это:

print(np.cbrt(a))

Ваш вывод будет:

[-10.   1. -10.   3. -10.   5.   6.   7.   8.   9.]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...