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