The Python Oracle

Will numpy keep order of assignment when existing duplicated indexes?

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Breezy Bay

--

Chapters
00:00 Will Numpy Keep Order Of Assignment When Existing Duplicated Indexes?
00:52 Answer 1 Score 2
01:23 Accepted Answer Score 0
01:44 Thank you

--

Full question
https://stackoverflow.com/questions/4467...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #arrays #numpy

#avk47



ANSWER 1

Score 2


Here's one approach to guarantee the assignment into the last indices from the group of identical indices -

# Get sorting indices for index keeping the order with 'mergesort' option
sidx = index.argsort(kind='mergesort')

# Get sorted index array
sindex = index[sidx]

# Get the last indices from each group of identical indices in sorted version
idx = sidx[np.r_[np.flatnonzero(sindex[1:] != sindex[:-1]), index.size-1]]

# Use those last group indices to select indices off index and b to assign
a[index[idx]] = b[idx]

Sample run -

In [141]: a
Out[141]: array([0, 1, 2, 3, 4])

In [142]: index
Out[142]: array([1, 2, 3, 1, 2, 1, 2, 3, 4, 2])

In [143]: b
Out[143]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [144]: sidx = index.argsort(kind='mergesort')
     ...: sindex = index[sidx]
     ...: idx = sidx[np.r_[np.flatnonzero(sindex[1:] != sindex[:-1]), index.size-1]]
     ...: a[index[idx]] = b[idx]
     ...: 

In [145]: a
Out[145]: array([0, 5, 9, 7, 8])



ACCEPTED ANSWER

Score 0


An simpler equivalent to Divakar's solution.

def assign_last(a, index, b):
    """a[index] = b
    """
    index = index[::-1]
    b = b[::-1]

    ix_unique, ix_first = np.unique(index, return_index=True)
    # np.unique: return index of first occurrence.
    # ix_unique = index[ix_first]

    a[ix_unique] = b[ix_first]
    return a

a =  array([0, 1, 2, 3, 4])
index = array([1, 2, 3, 1, 2, 1, 2, 3, 4, 2])
b = array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
assign_last(a, index, b)

Output

array([0, 5, 9, 7, 8])