Shift "nan" to the beginning of an array in python [duplicate]
Asked Answered
M

1

6

If I have an array with nan, which looks like this:

array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0., nan, nan],
       [ 0.,  1.,  3., nan],
       [ 0.,  2.,  4.,  7.],
       [ 0., nan,  2., nan],
       [ 0.,  4., nan, nan]])

how can I shift all the nans to the start of the array, without changing the shape? Some thing like this:

array([[ 0.,  0.,  0.,  0.],
       [ nan, nan, 0.,  0.],
       [ nan, 0.,  1.,  3.],
       [ 0.,  2.,  4.,  7.],
       [ nan, nan, 0.,  2.],
       [ nan, nan, 0.,  4.]])
Meggs answered 22/7, 2020 at 9:44 Comment(1)
Cool question. It's not hard to just code a solution, but I'm looking forward to performant answers leveraging numpy.Tolerance
W
4

Here's one way:

# find the position of nan itms in "a"
In [19]: mask = np.isnan(a)                                                                                                                                                                                 
# put them at the beginning by sorting the mask in a descending order
In [20]: nan_pos = np.sort(mask)[:,::-1]                                                                                                                                                                    
# the new position of non_non items is the inverse of non-mask sorted ascending 
In [21]: not_nan_pos = np.sort(~mask)                                                                                                                                                                       

In [22]: emp = np.empty(a.shape)                                                                                                                                                                            

In [23]: emp[nan_pos] = np.nan                                                                                                                                                                              

In [24]: emp[not_nan_pos] = a[~mask]                                                                                                                                                                        

In [25]: emp                                                                                                                                                                                                
Out[25]: 
array([[ 0.,  0.,  0.,  0.],
       [nan, nan,  0.,  0.],
       [nan,  0.,  1.,  3.],
       [ 0.,  2.,  4.,  7.],
       [nan, nan,  0.,  2.],
       [nan, nan,  0.,  4.]])
Waine answered 22/7, 2020 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.