0

I have created a dictionary in python like this:

 dictionary = dict(zip(numpy.arange(5), numpy.arange(5)*10))

And I use the dictionary as follows:

 y = np.vectorize(lambda x: dictionary[x])

Now I want to add a special situation: if the input x is an empty array, output also an empty array. And I tried to add an empty array in the dictionary:

 dictionary[np.array([], dtype='int64')] = np.array([], dtype='int64')

But I got an error:

*** TypeError: unhashable type: 'numpy.ndarray'

Why does it not work? How should I handle the empty array here?

8
  • 2
    You can't. A dict key can not be a mutable object. An empty list/array is a mutable object. It makes no sense for x to be an array (empty or not) when doing dict[x]. At most, x can be an empty tuple. Commented Sep 25, 2020 at 13:48
  • 1
    @f. c. Please check this answer https://stackoverflow.com/a/7027308/12420884 Commented Sep 25, 2020 at 13:49
  • 1
    I get ValueError: cannot call vectorize` on size 0 inputs unless otypes is set` if I attempt to just call y([]). It never gets to your function. If you pass in an array of numbers, your function will never get an empty array either. Commented Sep 25, 2020 at 13:58
  • 1
    Furthermore, this looks like a massive XY problem. I suspect that you need to explain what you are really trying to do. np.vectorize is almost never the right answer. Commented Sep 25, 2020 at 13:59
  • 1
    If your dictionary represents a mapping that can be represented as a function (as here), you are better off converting the function to a numpy pipeline than using np.vectorize. Commented Sep 25, 2020 at 14:00

1 Answer 1

1

Look at your dicitonary:

In [21]: dd = dict(zip(numpy.arange(5), numpy.arange(5)*10))
In [22]: dd
Out[22]: {0: 0, 1: 10, 2: 20, 3: 30, 4: 40}

the keys are numbers. The same thing can be produced without numpy:

In [23]: dict(zip(range(5), range(0,50,10)))
Out[23]: {0: 0, 1: 10, 2: 20, 3: 30, 4: 40}

Your vectorize array access:

In [29]: y = np.vectorize(lambda x: dd[x], otypes=[int])
In [30]: y([0,1,3])
Out[30]: array([ 0, 10, 30])
In [31]: y([])
Out[31]: array([], dtype=int64)

I added the otypes so that the [] works.

I don't see why you want to add an entry that has an array key. None of the other keys are arrays. And as you found out an array can't be a key.

dictionary[np.array([], dtype='int64')]

vectorize passes scalar values from the argument to your function. It does not pass an array. So there's no point to having an array, empty or not, as a key.

Whether np.vectorize is the best tool for using this dictionary is another question. Usually it doesn't improve speed over iterative access. Using a dictionary might the underlying problem, since it can only be accessed on key at a time.

===

Without the otypes, vectorize raises an error

ValueError: cannot call `vectorize` on size 0 inputs unless `otypes` is set

vectorize makes a trial call to the function to determine the return dtype.

===

Here's a more robust version of your y, one that won't choke on a missing key:

In [32]: y = np.vectorize(lambda x: dd.get(x,-100), otypes=[int])
In [33]: y([1,2,3,10])
Out[33]: array([  10,   20,   30, -100])
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.