84

From an array with three columns, I want to be able to just take a slice of data from all three columns where the values in the first column are equal to the values defined in above.

above = {1, 5, 10}
data = np.arange(9).reshape(-1, 3)
energies = np.hsplit(data, 3)[0]
slice = set(energies) & above

The above comes back with:

Traceback (most recent call last):
  File "<pyshell#27>", line 1, in <module>
    slice = set(energies) & above
TypeError: unhashable type: 'numpy.ndarray'

How do I resolve this error?

3 Answers 3

59

Your variable energies probably has the wrong shape:

>>> from numpy import array
>>> set([1,2,3]) & set(range(2, 10))
set([2, 3])
>>> set(array([1,2,3])) & set(range(2,10))
set([2, 3])
>>> set(array([[1,2,3],])) & set(range(2,10))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'numpy.ndarray'

And that's what happens if you read columnar data using your approach:

>>> data
array([[  1.,   2.,   3.],
       [  3.,   4.,   5.],
       [  5.,   6.,   7.],
       [  8.,   9.,  10.]])
>>> hsplit(data,3)[0]
array([[ 1.],
       [ 3.],
       [ 5.],
       [ 8.]])

Probably you can simply use

>>> data[:,0]
array([ 1.,  3.,  5.,  8.])

instead.

(P.S. Your code looks like it's undecided about whether it's data or elementdata. I've assumed it's simply a typo.)

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

2 Comments

Thank you very much for this answer. It worked perfectly and cleared things up for me. The data/elementdata was indeed a typo.
The shape difference here is between a hashable 1D and unhashable 2D numpy array.
5

numpy.ndarray can contain any type of element, e.g. int, float, string etc. Check the type an do a conversion if neccessary.

Comments

2

If you got this error while trying to get unique values in a numpy ndarray using set, consider using np.unique instead. It flattens multi-dimensional arrays as well. For example:

arr1 = np.array([[1, 2], [3, 1]])
unique_arr1 = np.unique(arr1)        # array([1, 2, 3])

If you want to find the intersection between two arrays (which seems to be the motivation in the OP), then you can use np.intersect1d instead of set.intersection:

arr2 = np.array([1, 3, 4, 5])
np.intersect1d(unique_arr1, arr2)    # array([1, 3])

For union:

np.union1d(unique_arr1, arr2)        # array([1, 2, 3, 4, 5])

Another way this error (seemingly unrelated to hashing numpy ndarrays) may show up is if you use a numpy statistical function such as max, std etc. on a pandas Series and a numpy ndarray. For example:

a = pd.Series([1, 2])
b = np.array([3, 1])
np.max(a, b)                 # TypeError: unhashable type: 'numpy.ndarray'
np.max((a, b))               # OK

This is because the second argument of max is axis=, so passing two arrays is not the correct way to compute the maximum values of these objects; they must be wrapped in a tuple/list.

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.