Сортировка значений по оси = 1 с NaNs в начале строки - PullRequest
0 голосов
/ 19 декабря 2018

Как отсортировать фрейм данных Pandas, отсортировать все значения столбцов в строке в порядке возрастания и сохранить значения NaN сначала

Пример кадра данных:

                       2018-07-01  2018-07-02  2018-07-03  2018-07-04  
cell_name                                                                                                                                            
1002_NUc_Marathalli_7        0.734       0.550       NaN         0.481             
1002_NUc_Marathalli_8        1.338       1.220       0.911       0.601       
1002_NUc_Marathalli_9        0.330       1.180       0.754       0.631       
1003_IU2_Munnekolalu_7       0.628       0.479       0.988       0.694       
1003_IU2_Munnekolalu_8       5.327       6.831       8.387       9.428       

Выходные данные должны бытьв

1002_NUc_Marathalli_7 NaN 0.481 0.550 0.734

Я могу создать другой фрейм данных, используя:

df1 = pd.DataFrame(np.sort(df.values,axis=1), index=df.index, columns=df.columns)

Но здесь значения nan идут в конце строки.Я хочу nan значения в первый

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Вы можете отсортировать строки данных, используя аргумент 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]
0 голосов
/ 19 декабря 2018

Вы можете использовать fillna(float('-inf')) и replace:

pd.DataFrame(
    np.sort(df.fillna(float('-inf')).values, axis=1), 
    index=df.index, 
    columns=df.columns
).replace(float('-inf'), np.nan)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...