<p>您可以使用<code>key</code>参数对数据帧行进行排序,以首先保留<code>NaNs</code>:</p>
<pre><code>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
</code></pre>
<p><b>说明</b></p>
<p>为了了解<code>sorted</code>在这种情况下的工作方式,让我们举个例子:</p>
^{pr2}$
<p>Sorted接受一个<code>key</code>参数,该参数可用于定义一个函数,在实际排序发生之前,使用该函数可以转换数据收集。在</p>
<p>那么在这种情况下有什么意义呢?理想的情况是有一些标准,根据这些标准我们可以确定序列中是否存在<code>np.nan</code>,并使这些情况排在第一位。如何转换数据以便以后<code>sorted</code>可以实现这一点?在</p>
<p>可以做的是为列表中的每一项添加一个额外的字段,该字段也将被用于对列表进行排序。假设我们有:</p>
<pre><code>lt = [(1, 0.734), (1, 0.481), (0, np.nan), (1, 0.550)]
</code></pre>
<p>所以本质上是一个标识符,用于判断是否每个元素上都是<code>NaN</code>。现在我们要做的是:</p>
<pre><code>sorted(lt)
[(0, nan), (1, 0.481), (1, 0.55), (1, 0.734)]
</code></pre>
<p><code>sorted</code>所做的是使用每个<code>tuple</code>中的两个项目进行排序,因此优先排序第一个元素(因此以<code>0</code>开头的元组排在第一个元素之前),其余的元素按第二个项排序,因为第一个元素是<code>1</code>。那么,有什么办法可以达到这个目的呢?在</p>
<p>如果将上面的<code>lambda</code>表达式重写为列表理解,它将等效于:</p>
<pre><code>sl = [(~np.isnan(s), s) for s in l]
print(sl)
[(True, 0.734), (True, 0.481), (False, nan), (True, 0.55)]
</code></pre>
<p>注意,tese布尔值已经足够了,因为它们被解释为<code>True==1</code>和{<cd14>},这将在本例中给出所需的顺序。如果我们这样做:</p>
<pre><code>sorted(sl)
[(False, nan), (True, 0.481), (True, 0.55), (True, 0.734)].
</code></pre>
<p>这可以在<code>key</code>参数中实现为<code>lambda</code>或匿名函数,如下所示:</p>
<pre><code>sorted(l, key = lambda s: (~np.isnan(s), s))
</code></pre>
<p>在上面的例子中,会给出:</p>
<pre><code>[nan, 0.481, 0.55, 0.734]
</code></pre>