Вы можете отсортировать строки данных, используя аргумент key
, чтобы сохранить NaNs
первым:
l = df.apply(sorted, key = lambda s: (~np.isnan(s), s), axis = 1)
pd.DataFrame(l.values.tolist(), columns=df.columns)
2018-07-01 2018-07-02 2018-07-03 2018-07-04
0 NaN 0.481 0.550 0.734
1 0.601 0.911 1.220 1.338
2 0.330 0.631 0.754 1.180
3 0.479 0.628 0.694 0.988
4 5.327 6.831 8.387 9.428
Объяснение
Чтобы увидеть путь sorted
работает в этом случае, давайте возьмем, к примеру:
l = [0.734, 0.481, np.nan, 0.550]
Sorted принимает аргумент key
, который можно использовать для определения функции, с помощью которой сбор данных может быть преобразован до того, как произойдет фактическая сортировка.место.
Так что имеет смысл в этом случае?В идеале, чтобы иметь некоторые критерии, по которым мы можем определить, есть ли np.nan
в последовательности, и сделать эти случаи на первом месте.Как можно преобразовать данные, чтобы в дальнейшем это можно было сделать sorted
?
Что можно сделать, добавить дополнительное поле для каждого элемента в списке, которое также будет учитываться для сортировкисписок.Скажем, вместо этого мы имеем:
lt = [(1, 0.734), (1, 0.481), (0, np.nan), (1, 0.550)]
Таким образом, по сути, это идентификатор того, является ли каждый элемент NaN
.Теперь, когда мы делаем:
sorted(lt)
[(0, nan), (1, 0.481), (1, 0.55), (1, 0.734)]
То, что sorted
услышал, - это сортировка по обоим элементам в каждом tuple
, поэтому приоритеты первого элемента (следовательно, кортежи, начинающиеся с 0
, стоят первыми)а для остальных он отсортирован по второму члену, так как первый - 1
.Так что может быть способом достичь этого?
Если приведенное выше выражение lambda
переписано в качестве списка, оно будет эквивалентно:
sl = [(~np.isnan(s), s) for s in l]
print(sl)
[(True, 0.734), (True, 0.481), (False, nan), (True, 0.55)]
Обратите внимание, что этих логических значений достаточно, поскольку они интерпретируются как * 1038.* и False==0
, что даст желаемый порядок в этом случае.Если мы сделаем:
sorted(sl)
[(False, nan), (True, 0.481), (True, 0.55), (True, 0.734)].
Это может быть реализовано в аргументе key
в виде lambda
или анонимной функции, например:
sorted(l, key = lambda s: (~np.isnan(s), s))
Что для приведенного выше примера, будетдать:
[nan, 0.481, 0.55, 0.734]