Reputation: 2405
I have a list with 0's in it that I want to change to np.nan for calculations in doing. I am trying to do the following which only replaces the first 0:
l = [0,2,3,4,0]
l[l == 0] = np.nan
print l
[nan,2,3,4,0]
Is there a way to do this substitution for every item in the list?
Upvotes: 2
Views: 7593
Reputation: 4311
Since you are already using numpy: your notation works, if l
was a numpy.array and not a list. However, it only works, if your entries are not integers, e.g. floats:
array = np.array(list, dtype=float)
array[array == 0] = np.nan
Now array looks like this:
array([ nan, 2., 3., 4., nan])
If you really need a list, then
l = list(array)
Upvotes: 1
Reputation: 8906
Here's a nice elegant way to do it:
l = [x or np.nan for x in l]
Upvotes: 0
Reputation: 352979
You can't use numpy vector boolean indexing or comparisons with a Python list, so your l == 0
is simply giving you 0. It's only a fluke it works even partially, because you happened to have 0 as the first element.
>>> l = [0,2,3,4,0]
>>> l == 0
False
>>> int(l == 0)
0
>>> l[l == 0] = 999
>>> l
[999, 2, 3, 4, 0]
You could use a list comprehension and a ternary:
>>> l = [0,2,3,4,0]
>>> l = [np.nan if x == 0 else x for x in l]
>>> l
[nan, 2, 3, 4, nan]
(If you were working with numpy arrays, vector comparisons and assignments would work, but you can't mix integers and floats (such as np.nan) too nicely.)
Upvotes: 7
Reputation: 126
You can just use the built in map:
l = map(lambda number: np.nan if number == 0 else number, l)
Which is equivalent to:
for i in range(len(l)):
l[i] = 0 if l[i] == np.nan else l[i]
Upvotes: 5