7

What would be the best way to return the first non nan value from this list?

testList = [nan, nan, 5.5, 5.0, 5.0, 5.5, 6.0, 6.5]

edit:

nan is a float

codeforester
  • 39,467
  • 16
  • 112
  • 140
user2333196
  • 5,406
  • 7
  • 31
  • 35

4 Answers4

11

You can use next, a generator expression, and math.isnan:

>>> from math import isnan
>>> testList = [float('nan'), float('nan'), 5.5, 5.0, 5.0, 5.5, 6.0, 6.5]
>>> next(x for x in testList if not isnan(x))
5.5
>>>
  • `next(x for x in testList if x == x)` would work too, and it's probably a bit faster since it avoids a lot of lookups for the function (although pretty unreadable). – Bakuriu Mar 02 '14 at 15:45
5

It would be very easy if you were using NumPy:

array[numpy.isfinite(array)][0]

... returns the first finite (non-NaN and non-inf) value in the NumPy array 'array'.

Decon
  • 81
  • 1
  • 4
  • Very clean and probably faster than manual looping. – user2647513 Oct 07 '21 at 04:25
  • I am surely not understanding something about this method, but it still seems the easiest one so I managed by creating the array of True and False value and counting whichever I need: `list(np.isfinite(array)).count(False)` – Sjotroll Oct 13 '22 at 14:10
3

If you're doing it a lot, put it into a function to make it readable and easy:

import math

t = [float('nan'), float('nan'), 5.5, 5.0, 5.0, 5.5, 6.0, 6.5]

def firstNonNan(listfloats):
  for item in listfloats:
    if math.isnan(item) == False:
      return item

firstNonNan(t)
5.5
atp
  • 30,132
  • 47
  • 125
  • 187
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
1

one line lambda below:

from math import isnan
lst = [float('nan'), float('nan'), 5.5, 5.0, 5.0, 5.5, 6.0, 6.5]

lst
[nan, nan, 5.5, 5.0, 5.0, 5.5, 6.0, 6.5]

first non nan value

lst[lst.index(next(filter(lambda x: not isnan(x), lst)))]
5.5

index of first non nan value

lst.index(next(filter(lambda x: not isnan(x), lst)))
2
Grant Shannon
  • 4,709
  • 1
  • 46
  • 36