Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shift NaNs to the end of their respective rows

I have a DataFrame like :

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

What I want to get is

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

This is my approach as of now.

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

Is there any efficient way to achieve this ? apply Here is way to slow . Thank you for your assistant!:)


My real data size

df.shape
Out[117]: (54812040, 1522)
like image 729
BENY Avatar asked Aug 30 '17 22:08

BENY


1 Answers

Here's a NumPy solution using justify -

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

If you want to save memory, assign it back instead -

df[:] = justify(df.values, invalid_val=np.nan, axis=1, side='left')
like image 67
Divakar Avatar answered Oct 03 '22 21:10

Divakar