sorted([2, float(\'nan\'), 1])
returns [2, nan, 1]
(At least on Activestate Python 3.1 implementation.)
I understand nan
Regardless of standards, there are many cases where a user-defined ordering of float and NA
values is useful. For instance, I was sorting stock returns and wanted highest to lowest with NA
last (since those were irrelevant). There are 4 possible combinations
NA
values lastNA
values firstNA
values lastNA
values firstHere is a function that covers all scenarios by conditionally replacing NA
values with +/- inf
import math
def sort_with_na(x, reverse=False, na_last=True):
"""Intelligently sort iterable with NA values
For reliable behavior with NA values, we should change the NAs to +/- inf
to guarantee their order rather than relying on the built-in
``sorted(reverse=True)`` which will have no effect. To use the ``reverse``
parameter or other kwargs, use functools.partial in your lambda i.e.
sorted(iterable, key=partial(sort_with_na, reverse=True, na_last=False))
:param x: Element to be sorted
:param bool na_last: Whether NA values should come last or first
:param bool reverse: Return ascending if ``False`` else descending
:return bool:
"""
if not math.isnan(x):
return -x if reverse else x
else:
return float('inf') if na_last else float('-inf')
Testing out each of the 4 combinations
from functools import partial
a = [2, float('nan'), 1]
sorted(a, key=sort_with_na) # Default
sorted(a, key=partial(sort_with_na, reverse=False, na_last=True)) # Ascend, NA last
sorted(a, key=partial(sort_with_na, reverse=False, na_last=False)) # Ascend, NA first
sorted(a, key=partial(sort_with_na, reverse=True, na_last=True)) # Descend, NA last
sorted(a, key=partial(sort_with_na, reverse=True, na_last=False)) # Descend, NA first