1

I'm attempting to sort a dictionaries keys according to its values. So I have used numpy's argsort to sort the values in ascending order. But when I attempt to sort the keys according to the values indices I get the error:

IndexError: too many indices for array

What am I doing wrong here?

import numpy as np

## Map occurences of colours in image
colour_map = {}
#...
colour_map['#fff'] = 15
colour_map['#ccc'] = 99
#...

## Sort colour map from most frequent to least 
colours         = np.array(colour_map.keys())   # dict_keys(['#fff', '#ccc'])
col_frequencies = np.array(colour_map.values()) # dict_values([15, 99])

indicies = col_frequencies.argsort()

# Error on below line "IndexError: too many indices for array"
colours = colours[indicies[::-1]]
7
  • 2
    When you call .keys() and values() numpy doesn't convert them to char or integer arrays but instead object arrays. colours = np.array(list(colour_map.keys())) followed by col_frequencies = np.array(list(colour_map.values())) should solve this. Commented Oct 11, 2017 at 12:01
  • @ayhan Thanks that fixed it. If you make an answer I can accept it. Commented Oct 11, 2017 at 12:09
  • Your code works fine as-is on Python 2.7.12 with Numpy 1.13.0. Commented Oct 11, 2017 at 12:09
  • @carthurs doesn't work in Python 3.6 Commented Oct 11, 2017 at 12:16
  • @JakeM I still couldn't figure out why colours[0] raises an error. It's an array with a single item after all. Maybe someone can come up with an explanation. Commented Oct 11, 2017 at 13:33

1 Answer 1

0

In Python 3, dir(np.array(colour_map.keys())) shows that this class not satisfy the array_like requirement which is specified as being necessary in the documentation for numpy.array https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.array.html

The definition of array_like was explored in more detail here numpy: formal definition of "array_like" objects?

It seems that np.array doesn't check whether array_like is satisfied, and will happily construct a Numpy array from an object which does not satisfy it.

Then when you try to index it, the indexing doesn't work.

Here's an example with my_object designed not to be array_like.

class my_object():
    def greet(self):
        print("hi!")

a = my_object()
a.greet()
print(dir(a))  # no __array__ attribute

b = np.array(a)

b[0]

results in

hi!
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'greet']
Traceback (most recent call last):
  File "C:/path/to/my/script.py", 
line 35, in <module>
    b[0]
IndexError: too many indices for array

Now let's try making it array-like (or at least sufficiently array-like for this to work):

class my_object():
    def greet(self):
        print("hi!")

    def __array__(self):
        return np.array([self])

a = my_object()

b = np.array(a)

b[0].greet()  # Now we can index b successfully

results in:

hi!
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.