如何对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
值
答案 0 :(得分:1)
您可以使用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)
答案 1 :(得分:1)
您可以使用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)]
请注意,布尔值足够了,因为它们被解释为True==1
和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]