Home > Back-end >  on restoring the original order of row elements
on restoring the original order of row elements

Time:12-01

Consider numpy array p shown below. Unique values 0 to 9 are used in each row. The distinguishing characteristic is that every row is composed of 5 (in this case) values PAIRED with 5 other values. Pairs are formed when p[k] = p[p[k]] for k = 0 to 9.

p = np.array([[1, 0, 3, 2, 5, 4, 7, 6, 9, 8], 
             ... 
             [6, 5, 3, 2, 9, 1, 0, 8, 7, 4],
             ...
             [9, 8, 5, 7, 6, 2, 4, 3, 1, 0]])

Examine, for example, the row:

[6, 5, 3, 2, 9, 1, 0, 8, 7, 4]

This row pairs values 6 and 0 because p[6] = 0 and p[0] = 6. Other pairs are values (5, 1), (3, 2), (9, 4), (8, 7). Different rows may have different arrangements of pairs.

Now, we are interested here in the 1st value of each pair (ie: 6, 5, 3, 9, 8) and the 2nd value of each pair (ie: 0, 1, 2, 4, 7) I'm not sure this is the best way to proceed, but I've separated the 1st pair values from the 2nd pair values this way:

import numpy as np

p = np.array([6, 5, 3, 2, 9, 1, 0, 8, 7, 4])

p1 = np.where(p[p] < p)   # indices of 1st member of pairs
p2 = (p[p1])              # indices of 2nd member of pairs

qi = np.hstack((p1, p2.reshape(1,5)))
qv = p[qi]

#output: qi = [0, 1, 2, 4, 7,   6, 5, 3, 9, 8]   #indices of 1st of pair values, followed by 2nd of pair values 
#        qv = [6, 5, 3, 9, 8,   0, 1, 2, 4, 7]   #corresponding values

Finally consider another 1D array: c = [1, 1, 1, 1, 1, -1, -1, -1, -1, -1].

I find c*qv, giving:

out1 = [6, 5, 3, 9, 8, 0, -1, -2, -4, -7]

QUESTION: out1 holds the correct values, but I need them to be in the original order (as found in p). How can this be achieved? I need to get:

out2 = [6, 5, 3, -2, 9, -1, 0, 8, -7, -4]

CodePudding user response:

You can reuse p1 and p2, which hold the original position information.

out2 = np.zeros_like(out1)
out2[p1] = out1[:5]
out2[p2] = out1[5:]

print(out2)
# [ 6  5  3 -2  9 -1  0  8 -7 -4]

Can also use qi to similar effect, but even neater.

out2 = np.zeros_like(out1)
out2[qi] = out1

Or using np.put in case you don't want to create out2:

np.put(out1, qi, out1)

print(out1)
# [ 6  5  3 -2  9 -1  0  8 -7 -4]
  • Related