Skip to content
Advertisement

How to cycle the NaNs in pandas dataframe rows?

I have a dataframe like this:

df = pd.DataFrame({0: list('wxyz'), 1: [1,2,None,None], 2: [10,20,30,None]}).T
print(df)

    0   1    2    3
0   w   x    y    z
1   1   2  NaN  NaN
2  10  20   30  NaN

How to put all the NAs in the left instead of right?

Required:

    0   1    2    3
0   w   x    y    z
1  NaN  NaN  1    2
2  NaN  10  20   30

Advertisement

Answer

There are mixed numeric with strings rows, so solution is use sorted with key parameter in DataFrame.apply:

df = df.apply(lambda x: pd.Series(sorted(x, key=pd.notna)), axis=1)
#alternative
#df = df.apply(lambda x: sorted(x, key=pd.notna), axis=1, result_type='expand')
print (df)

     0    1   2   3
0    w    x   y   z
1  NaN  NaN   1   2
2  NaN   10  20  30

If all values are numeric, faster solution is with justify:

df = pd.DataFrame({1: [1,2,None,None], 2: [10,20,30,None]}).T
print(df)
      0     1     2   3
1   1.0   2.0   NaN NaN
2  10.0  20.0  30.0 NaN

arr = justify(df.values, invalid_val=np.nan, side='right')
df = pd.DataFrame(arr, index=df.index, columns=df.columns)
print (df)
    0     1     2     3
1 NaN   NaN   1.0   2.0
2 NaN  10.0  20.0  30.0
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement