I have a dataframe like this:
JavaScript
x
8
1
df = pd.DataFrame({0: list('wxyz'), 1: [1,2,None,None], 2: [10,20,30,None]}).T
2
print(df)
3
4
0 1 2 3
5
0 w x y z
6
1 1 2 NaN NaN
7
2 10 20 30 NaN
8
How to put all the NAs in the left instead of right?
Required:
JavaScript
1
5
1
0 1 2 3
2
0 w x y z
3
1 NaN NaN 1 2
4
2 NaN 10 20 30
5
Advertisement
Answer
There are mixed numeric with strings rows, so solution is use sorted
with key
parameter in DataFrame.apply
:
JavaScript
1
10
10
1
df = df.apply(lambda x: pd.Series(sorted(x, key=pd.notna)), axis=1)
2
#alternative
3
#df = df.apply(lambda x: sorted(x, key=pd.notna), axis=1, result_type='expand')
4
print (df)
5
6
0 1 2 3
7
0 w x y z
8
1 NaN NaN 1 2
9
2 NaN 10 20 30
10
If all values are numeric, faster solution is with justify:
JavaScript
1
13
13
1
df = pd.DataFrame({1: [1,2,None,None], 2: [10,20,30,None]}).T
2
print(df)
3
0 1 2 3
4
1 1.0 2.0 NaN NaN
5
2 10.0 20.0 30.0 NaN
6
7
arr = justify(df.values, invalid_val=np.nan, side='right')
8
df = pd.DataFrame(arr, index=df.index, columns=df.columns)
9
print (df)
10
0 1 2 3
11
1 NaN NaN 1.0 2.0
12
2 NaN 10.0 20.0 30.0
13