Reputation: 6854
I have an OrderedDict
:
from collections import OrderedDict
d = OrderedDict([('r', 1), ('s', 5), ('a', 3), ('n', 7), ('y', 2)])
I'd like to get indices of dictionary values according to values range. For example, indices of dictionary d
should be array (or np.array
), like following:
indices
array([ 0, 3, 2, 4, 1 ], dtype=int64)
index 4
is a biggest value in dictionary, index 0
is smallest value
I tried :
indices = np.argsort(d.values)
Upvotes: 1
Views: 161
Reputation:
Since you've tried with argsort:
np.argsort(d.values()).argsort()
Out[50]: array([0, 3, 2, 4, 1], dtype=int64)
So argsort does not actually return their orders but it returns the indices that would sort that array. Calling argsort on that result does what you want.
Upvotes: 2
Reputation: 6854
At the end I forgot to put ()
after values , so I used indices = np.argsort(d.values())
Upvotes: 0
Reputation: 36033
The other answer is nice and simple but is O(n^2)
as each .index
is O(n)
. You can precompute the indices in a dictionary so that the index lookups are O(1)
, making the whole thing O(nlogn)
as the sort is the most expensive part. If d
is large enough this will be a very important difference.
>>> from itertools import izip
>>> indices = dict(izip(sorted_values, xrange(len(d))))
>>> indices
{1: 0, 2: 1, 3: 2, 5: 3, 7: 4}
>>> [indices[v] for v in d.itervalues()]
[0, 3, 2, 4, 1]
Here I've used xrange
instead of range
, izip
instead of zip
, and itervalues
instead of values
for memory efficiency.
Upvotes: 0
Reputation: 59228
You can use a list comprehension to implement this:
>>> values = d.values()
>>> sorted_values = sorted(values)
>>> [sorted_values.index(item) for item in values]
[0, 3, 2, 4, 1]
Upvotes: 2