1

I have two lists in python3.6, and I would like to sort w by considering d values. This is similar to this question, Sorting list based on values from another list? , though, I could not use zip because w and d are not paired data.

I have a code sample, and want to get t variable.

Updated

I could do it by using for loop. Is there any fasterh way?

import numpy as np

w = np.arange(0.0, 1.0, 0.1)
t = np.zeros(10)
d = np.array([3.1, 0.2, 5.3, 2.2, 4.9, 6.1, 7.7, 8.1, 1.3, 9.4])
ind = np.argsort(d)
print('w', w)
print('d', d)

for i in range(10):
    t[ind[i]] = w[i]

print('t', t)
#w [ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9]
#d [ 3.1  0.2  5.3  2.2  4.9  6.1  7.7  8.1  1.3  9.4]
#ht [ 0.3  0.   0.5  0.2  0.4  0.6  0.7  0.8  0.1  0.9]
jef
  • 3,890
  • 10
  • 42
  • 76
  • 4
    *I could not use zip because w and d are not paired data.* <- What does this mean? – Srini Jun 15 '18 at 21:41
  • In the referred question, X and Y are pair data. But in my example, w and d are not pair data. `sort(zip(d, w))` is not suitable. – jef Jun 15 '18 at 21:42
  • 1
    It looks like your example `t` output data is in the wrong order. You want `t = [ 0.1, 0.8, 0.3, 0.0, 0.4, 0.2, 0.5, 0.6, 0.7, 0.9]`, right? – Tim Johns Jun 15 '18 at 21:42
  • @TimJohns No. I want to sort `w` by `d`'s values. – jef Jun 15 '18 at 21:44
  • 1
    Maybe I'm missing something, but I thought I _did_ sort `w` by `d`'s values. For example, the lowest `d` value is `0.2`, which corresponds to `0.1` in `w`. Hence why `0.1` is the first element in the `t` output that I provided. Am I misunderstanding what you want to achieve here? – Tim Johns Jun 15 '18 at 21:47
  • zip will make it paired data.you fuse `d`and `w` with `zip`. Sort this fused list and extract the second element of the each tuple in the sorted list. Look Prune's answer, they have detailed the algorithm – Srini Jun 15 '18 at 21:48
  • I'm sorry. My explanation was bad. I added a working sample. – jef Jun 15 '18 at 21:51

3 Answers3

3

Use argsort like so:

>>> t = np.empty_like(w)
>>> t[d.argsort()] = w
>>> t
array([0.3, 0. , 0.5, 0.2, 0.4, 0.6, 0.7, 0.8, 0.1, 0.9])
Paul Panzer
  • 51,835
  • 3
  • 54
  • 99
1

They are paired data, but in the opposite direction.

  • Make a third list, i, np.arange(0, 10).
  • zip this with d.
  • Sort the tuples with d as the sort key; i still holds the original index of each d element.
  • zip this with w.
  • Sort the triples (well, pairs with a pair as one element) with i as the sort key.
  • Extract the w values in their new order; this is your t array.
Prune
  • 76,765
  • 14
  • 60
  • 81
1

The answers for this question are fantastic, but I feel it is prudent to point out you are not doing what you think you are doing.

What you want to do: (or at least what I gather) You want t to contain the values of w rearranged to be in the sorted order of d

What you are doing: Filling out t in the sorted order of d, with elements of w. You are only changing the order of how t gets filled up. You are not reflecting the sort of d into w on t

Consider a small variation in your for loop

for i in range(0,10):
    t[i] = w[ind[i]]

This outputs a t

('t', array([0.1, 0.8, 0.3, 0. , 0.4, 0.2, 0.5, 0.6, 0.7, 0.9]))

You can just adapt PaulPanzer's answer to this as well.

Srini
  • 1,619
  • 1
  • 19
  • 34
  • 1
    Thank you for your comment. I am a little confused about my problem. Your answer is easy to understand what I am doing now. – jef Jun 15 '18 at 22:06