2017-08-30 14 views
2

我有一個數據幀,如:移NaN的各自列的底部

 0 1 2 
0 0.0 1.0 2.0 
1 NaN 1.0 2.0 
2 NaN NaN 2.0 

我想要得到的是

Out[116]: 
    0 1 2 
0 0.0 1.0 2.0 
1 1.0 2.0 NaN 
2 2.0 NaN NaN 

這是我作爲的做法現在。

df.apply(lambda x : (x[x.notnull()].values.tolist()+x[x.isnull()].values.tolist()),1) 
Out[117]: 
    0 1 2 
0 0.0 1.0 2.0 
1 1.0 2.0 NaN 
2 2.0 NaN NaN 

有沒有什麼有效的方式來實現這一目標? apply這是減速的方法。 謝謝您的助手!:)


我真正的數據大小

df.shape 
Out[117]: (54812040, 1522) 
+0

能夠保證所有的NaN是位於鄰近的細胞? –

+0

@cᴏʟᴅsᴘᴇᴇᴅ有時它會是1 NaN 2 NaN – Wen

+0

難道你不是在將NaN移動到每個行的右側嗎? – Divakar

回答

2

下面是使用justify一個NumPy的解決方案 -

In [455]: df 
Out[455]: 
    0 1 2 
0 0.0 1.0 2.0 
1 NaN 1.0 2.0 
2 NaN NaN 2.0 

In [456]: pd.DataFrame(justify(df.values, invalid_val=np.nan, axis=1, side='left')) 
Out[456]: 
    0 1 2 
0 0.0 1.0 2.0 
1 1.0 2.0 NaN 
2 2.0 NaN NaN 

如果你想節省內存,分配回代替 -

df[:] = justify(df.values, invalid_val=np.nan, axis=1, side='left') 
+0

不錯的一個,謝謝〜 – Wen

+0

@Wen很高興知道您在數據集中獲得的時間種類。 – Divakar

+0

我正在處理它〜〜: – Wen

2

最佳最簡單的選擇是使用sorteddf.apply/df.transform和排序無效。

df = df.apply(lambda x: sorted(x, key=pd.isnull), 1) 
df 
    0 1 2 
0 0.0 1.0 2.0 
1 1.0 2.0 NaN 
2 2.0 NaN NaN 

您也可以傳遞np.isnankey說法。

+0

我應該說得更清楚,有時候它會是'1 NaN 2 NaN',還算不錯!:) – Wen

+0

@Wen增加了另一種解決方案。 –

+1

夥計,你殺了它!我完全忘記了'排序的鍵'讓我用我的真實數據來測試它 – Wen