lordy
lordy

Reputation: 630

Replacing 0 values of np array with nan in an easy way

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

Answers (2)

Amadan
Amadan

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

yatu
yatu

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

Related Questions