I have a list of strings
x = ['A', 'B', nan, 'D']
and want to remove the nan.
I tried:
x = x[~numpy.isnan(x)]
But that only works if it contains numbers. How do we solve this for strings in Python 3+?
If you have a numpy array you can simply check the item is not the string nan, but if you have a list you can check the identity with is and np.nan since it's a singleton object.
In [25]: x = np.array(['A', 'B', np.nan, 'D'])
In [26]: x
Out[26]:
array(['A', 'B', 'nan', 'D'],
dtype='<U3')
In [27]: x[x != 'nan']
Out[27]:
array(['A', 'B', 'D'],
dtype='<U3')
In [28]: x = ['A', 'B', np.nan, 'D']
In [30]: [i for i in x if i is not np.nan]
Out[30]: ['A', 'B', 'D']
Or as a functional approach in case you have a python list:
In [34]: from operator import is_not
In [35]: from functools import partial
In [37]: f = partial(is_not, np.nan)
In [38]: x = ['A', 'B', np.nan, 'D']
In [39]: list(filter(f, x))
Out[39]: ['A', 'B', 'D']
[i for i in x if not i in ['nan', np.nan]], +1 otherwisenp.nan?np.nan is just some floating point constant. You wouldn't compare is math.pi either, for the same reason.You can use math.isnan and a good-old list comprehension.
Something like this would do the trick:
import math
x = [y for y in x if not math.isnan(y)]
math.isnan('A')? Test on the OP's x?You may want to avoid np.nan with strings, use None instead; but if you do have nan you could do this:
import numpy as np
[i for i in x if i is not np.nan]
# ['A', 'B', 'D']
nan in string cases, which will be converted to a string nan but None stays as None.is. This will fail.
nonobject from numpy module which the OP is using. I change it to numpy so that the future askers can find the question easily.