Простая замена 0 значений массива np на nan - PullRequest
1 голос
/ 10 января 2020

Кажется, в принципе, массив np может содержать значения nan, но ему не нравится, когда они записываются после первоначального распределения? Кто-нибудь может пролить свет на это и, возможно, предложить более простой способ, как сделать замену, чем у меня в примере 5?

import numpy as np

a = np.array([2,1,0,7])
a[a==0] = -999  # replacing this way with numbers works
print (a)

a = np.array([2,1,np.nan,7])  # allocating an np array with nans works
print (a)

a = np.array([2,1,0,7])
a[a==0] = np.nan   # trying the frist approach with nan instead of a number gives ValueError: cannot convert float NaN to integer

a = np.array([2,1,0,7])
a[2] = np.nan   #  also writing to one specific position does not work: ValueError: cannot convert float NaN to integer
print (a)

# works - but this cant be the way to do it normally?
a = np.array([2,1,0,7])
a = list(a)
for idx, elem in enumerate(a):
    if elem == 0:
        a[idx] = np.nan
a = np.array(a)
print(a)

Ответы [ 2 ]

2 голосов
/ 10 января 2020
np.array([2,1,0,7]).dtype
# => dtype('int64')
np.array([2,1,np.nan,7]).dtype
# => dtype('float64')

Целые числа не имеют значения NaN; np.nan - это число с плавающей точкой, и его нельзя поместить в целочисленный массив.

roganjo sh побеждает меня в решении, хотя: P (то есть преобразовать в массив с плавающей точкой, прежде чем пытаться поместить np.nan там). С разрешения roganjo sh:

a = np.array([2,1,0,7])
a = a.astype(np.float64)
a[a == 0] = np.nan
a
# => array([ 2.,  1., nan,  7.])

Причина, по которой преобразование в list работает, заключается в том, что списки, в отличие от массивов numpy, не против смешивать типы элементов. Когда вы преобразуете смешанный список целых чисел и чисел с плавающей точкой, numpy будет предполагать, что вам нужен массив с плавающей точкой.

1 голос
/ 10 января 2020

Как упоминалось в комментариях, проблема в том, что a имеет тип int, а np.nan имеет тип float, поэтому он не может быть напрямую назначен или приведен к типу int, поскольку он определен только для типов с плавающей точкой.

Вы должны были бы инициализировать массив с плавающей точкой, чтобы назначение среза работало:

a = np.array([2,1,0,7], dtype=float)
a[a==0] = np.nan

print(a)
# array([ 2.,  1., nan,  7.])
...