Reputation: 630
It seems in principle an np array can hold nan values but it does not like them to be written into after initial allocation? Can anybody shed light on this and maybe suggest an easier way of how to do the replacement than what I have in example 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)
Upvotes: 2
Views: 2049
Reputation: 198314
np.array([2,1,0,7]).dtype
# => dtype('int64')
np.array([2,1,np.nan,7]).dtype
# => dtype('float64')
Integers don't have a NaN value; np.nan
is a float, and can't be placed in an integral array.
roganjosh beat me to the solution though :P (i.e. convert to a float array before trying to put a np.nan
in there). With roganjosh's permission:
a = np.array([2,1,0,7])
a = a.astype(np.float64)
a[a == 0] = np.nan
a
# => array([ 2., 1., nan, 7.])
The reason why converting to list
works is the fact that lists, unlike numpy arrays, don't mind mixing element types. When you re-convert a mixed list of integers and floats, numpy will assume you wanted a float array.
Upvotes: 2
Reputation: 88236
As mentioned in the comments, the problem is that a is of type int
, and np.nan
is of type float, so it cannot by directly assigned nor cast to int since it is only defined for float types.
You'd have to initialize an array of floats for the slice assignment to work:
a = np.array([2,1,0,7], dtype=float)
a[a==0] = np.nan
print(a)
# array([ 2., 1., nan, 7.])
Upvotes: 1