Home > Software engineering >  How to sort and array by indices sequence of another array
How to sort and array by indices sequence of another array

Time:10-13

Given I have two arrays:

array1 = np.array([np.nan,np.nan,np.nan,np.nan,2,np.nan,1,np.nan,np.nan,5,np.nan,np.nan,6,np.nan,10,9,np.nan])
array2 = np.array([np.nan,np.nan,np.nan,np.nan,45,np.nan,33,np.nan,np.nan,32,np.nan,np.nan,44,np.nan,10,53,np.nan])

I want to get array2 sorted in ascending order of array1 elements with same nan sequence: [np.nan,np.nan,np.nan,np.nan,32,np.nan,10,np.nan,np.nan,33,np.nan,np.nan,44,np.nan,53,45,np.nan]

Seems I could use np.argsort(array1) = [ 6 4 9 12 15 14 0 13 11 10 8 5 3 2 1 7 16] if there's a command to move elements in array2 like : put an element with index "6" to the first not nan place etc

Any ideas?

CodePudding user response:

Remove NaN, sort, add NaN.

from operator import itemgetter

#remove NaN
a = [x for x in array1 if not np.isnan(x)]
b = [y for y in array2 if not np.isnan(y)]
# a == [2.0, 1.0, 5.0, 6.0, 10.0, 9.0]
# b == [45.0, 33.0, 32.0, 44.0, 10.0, 53.0]


# sort
c = map(itemgetter(1), sorted(zip(a, b)))
# list(c) == [33.0, 45.0, 32.0, 44.0, 53.0, 10.0]

# add NaN
d = [(np.nan if np.isnan(x) else next(c)) for x in array1]
# d == [nan, nan, nan, nan, 33.0, nan, 45.0, nan, nan, 32.0, nan, nan, 44.0, nan, 53.0, 10.0, nan]

Note that the suggestion in Akshay Sehgal's answer is likely faster than mine, since it uses numpy directly rather than python lists and iterators.

CodePudding user response:

You can do this with numpy by overwriting the view over the second array for non nan elements.

idx = array1[~np.isnan(array1)].argsort()

array2[~np.isnan(array2)] = array2[~np.isnan(array2)][idx]
array2
array([nan, nan, nan, nan, 33., nan, 45., nan, nan, 32., nan, nan, 44.,
       nan, 53., 10., nan])

Another "cleaner" way to do this is to just sort the arrays as is, remove nans and then overwrite the view for array2 as in the previous approach.

ordered = array2[array1.argsort()]
ordered = ordered[~np.isnan(ordered)]

array2[~np.isnan(array2)] = ordered
array2
array([nan, nan, nan, nan, 33., nan, 45., nan, nan, 32., nan, nan, 44.,
       nan, 53., 10., nan])
  • Related