2

I have two lists

a = ['E300' 'E407' 'nan' 'nan' 'nan' 'nan' 'nan' 'nan' 'nan' 'nan' ]
b = [ nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan  nan]

I wanted to remove nan from the lists. So I used this on list 'a' and 'b'

a = [x for x in a if x != 'nan']
b = [x for x in b if x != 'nan']

So it works fine for list 'a' because I think it was taking 'nan' as a string but not with list b. How can I remove those nan from list b. Thanks in advance.

dawg
  • 98,345
  • 23
  • 131
  • 206
muazfaiz
  • 4,611
  • 14
  • 50
  • 88

3 Answers3

12

When you don't put it in quotes, nan is a number (it's a special number used to represent a nonexistent result, called "Not a Number"). It's so special that it doesn't even equal itself. Use math.isnan or numpy.isnan to test if a number is nan

b = [x for x in b if not math.isnan(x)]
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • This is the perfect answer if you add that `nan` has signal properties to floating point operations in the IEEE specifications... – dawg Oct 28 '16 at 17:02
  • @dawg I'm not sure how that's relevant to the question of how to remove it from the list. – Barmar Oct 28 '16 at 17:03
  • +1 for giving this method. I am a newbie in python too. I wonder since `nan` comes from `numpy`, why doesn't `numpy` provides a method for checking the `nan`, something like `pandas.isnull()` does. Any idea? – Psidom Oct 28 '16 at 17:03
  • 1
    when use `!`, do you mean `not`? – Haifeng Zhang Oct 28 '16 at 17:04
  • 1
    @Psidom [numpy.isnan](https://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html) – Barmar Oct 28 '16 at 17:04
  • Ah. shame on me. Just didn't know that before. – Psidom Oct 28 '16 at 17:05
  • @HaifengZhang Thanks. I don't use Python regularly enough to remember some of its differences from other languages. – Barmar Oct 28 '16 at 17:06
1

'nan' is a string, but nan is a floating-point number. Which is funny, because "nan" stands for Not A Number, but that's really what it is:

>>> type(nan)
<class 'float'>

nan has a number of tricky properties, and one of the trickiest is that it compares unequal to everything, including itself. You have to use a special function to check for it, math.isnan.

>>> b
[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
>>> [x for x in b if x != nan]
[nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]
>>> [x for x in b if not math.isnan(x)]
[]

Note: Python does not define a built-in constant nan, even though the repr of a NaN value is nan. (Contrast True, False, None, etc.) 3.5 and later have math.nan, but before that you have to say float('nan').

zwol
  • 135,547
  • 38
  • 252
  • 361
  • Actually `nan`, `inf` and `-inf`. are floating-point values but not floating-point numbers . – Stop harming Monica Oct 28 '16 at 17:24
  • @Goyo A mathematician would agree with you, but a programming language designer wouldn't. In Python, a floating-point number is any value with type `float`, and `nan` and `±inf` are included. – zwol Oct 28 '16 at 17:43
  • You are right, in Python, all instances of `float` are called numbers. I assumed incorrectly that the language specification would make a difference. Out of curiosity I checked IEEE-758-2008 (the last revision of the standard that languages are expected to follow... well, more or less) and it says that NaNs are not floating-point numbers but infinities are. – Stop harming Monica Oct 28 '16 at 19:24
0

'nan' is a string

nan is Not A number, you can check it by method math.isnan()

>>> nan=float('nan')
>>> math.isnan(nan)
True

In your case:

b = [x for x in b if not math.isnan(x)]
Haifeng Zhang
  • 30,077
  • 19
  • 81
  • 125