Reputation: 493
I'm attempting to map numpy dtypes to associated values using a dictionary lookup. I observe the following counterintuitive behavior:
dtype = np.uint16
x = np.array([0, 1, 2], dtype=dtype)
assert x.dtype == dtype
d = {np.uint8: 8, np.uint16: 16, np.uint32: 32, np.float32: 32}
print(dtype in d) # prints True
print(x.dtype in d) # prints False
Using other dtypes produces similar results.
So we have that np.uint16 == x.dtype
, but the former is found in the dictionary's keys while the latter is not. Any explanation and/or simple workaround would be appreciated.
Upvotes: 7
Views: 12041
Reputation: 281843
Dtypes don't work like they look at first glance. np.uint16
isn't a dtype object. It's just convertible to one. np.uint16
is a type object representing the type of array scalars of uint16 dtype.
x.dtype
is an actual dtype object, and dtype objects implement ==
in a weird way that's non-transitive and inconsistent with hash
. dtype == other
is basically implemented as dtype == np.dtype(other)
when other
isn't already a dtype. You can see the details in the source.
Particularly, x.dtype
compares equal to np.uint16
, but it doesn't have the same hash, so the dict lookup doesn't find it.
Upvotes: 10
Reputation: 1606
This is the expected behavior:
np.uint16
is non-initialized and therefore dtype
is actually a class, whereas x.dtype
is actually a data type object (documentation).
Another answer shows a workaround here.
Upvotes: 1
Reputation: 2438
x.dtype
returns a dtype
object (see dtype class)
To get the type inside, you need to call x.dtype.type
:
print(x.dtype.type in d) # True
Upvotes: 2