如何将每个 Pandas 数据帧行中的 np.nan 值移动到其它位置?

4
如果我有这样的一个pandas数据框:
      A   B   C   D   E   F   G   H 
 0    0   2   3   5  NaN NaN NaN NaN
 1    2   7   9   1   2  NaN NaN NaN
 2    1   5   7   2   1   2   1  NaN
 3    6   1   3   2   1   1   5   5
 4    1   2   3   6  NaN NaN NaN NaN

我该如何将每行中所有的数值移到末尾,并将NAN放在它们之前,以便获得以下这样一个 Pandas 数据框?
      A   B   C   D   E   F   G   H 
 0   NaN NaN NaN NaN  0   2   3   5
 1   NaN NaN NaN  2   7   9   1   2  
 2   NaN  1   5   7   2   1   2   1 
 3    6   1   3   2   1   1   5   5
 4   NaN NaN NaN NaN  1   2   3   6  

查看Divakar的这个答案,并使用:pd.DataFrame(justify(df.values,np.nan,side='right'),columns=df.columns) - anky
2个回答

3

一行解决方案:

df.apply(lambda x: pd.concat([x[x.isna()==True], x[x.isna()==False]], ignore_index=True), axis=1)

2

我认为最好的方法是逐行工作。编写一个函数来完成任务,并使用applytransform在每一行上使用该函数。

def movenan(x):
    fl = len(x)
    nl = len(x.dropna())
    nanarr = np.empty(fl - nl)
    nanarr[:] = np.nan
    return pd.concat([pd.Series(nanarr), x.dropna()], ignore_index=True)

ddf = df.transform(movenan, axis=1)
ddf.columns = df.columns

使用您的示例数据,生成的 ddf 如下:
     A    B    C    D    E    F    G    H
0  NaN  NaN  NaN  NaN  0.0  2.0  3.0  5.0
1  NaN  NaN  NaN  2.0  7.0  9.0  1.0  2.0
2  NaN  1.0  5.0  7.0  2.0  1.0  2.0  1.0
3  6.0  1.0  3.0  2.0  1.0  1.0  5.0  5.0
4  NaN  NaN  NaN  NaN  1.0  2.0  3.0  6.0

movenan函数会创建指定长度的nan数组,然后将行中的nan删除,并将两个结果序列连接起来。
ignore_index=True是必须的,因为您不希望保留数据在其列中的位置(值被移动到不同的列),但这样做会丢失列名并被整数替换。最后一行只是将列名复制回新的数据框中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接