Maciek
Maciek

Reputation: 792

How to use isinstance() on a numpy structured array custom type

In the below example I create a custom type, then an array of elements of this type and then I test the first element of this array against this type with isinstance(), but I get an Error.

import numpy as np

# Here I define a simple type with two fields
my_type_simple = np.dtype([('field_1', int), ('field_2', float)])
# An array using the above type
my_var_simple_1 = np.array([(1, 1), (2, 2)], dtype=my_type_simple)
# For a check, should print [(1, 1.) (2, 2.)]
print(my_var_simple_1)
# For a check, should print True
print(isinstance(my_var_simple_1, np.ndarray))
# The below prints numpy.void - how can I find out that in fact it is 'my_type_simple' ?
print(type(my_var_simple_1[0]))
# The below prints True, at least
print(isinstance(my_var_simple_1[0], type(my_var_simple_1[0])))
# But the below raises an Error: TypeError: isinstance() arg 2 must be a type or tuple of types
print(isinstance(my_var_simple_1[0], my_type_simple))

Therefore the question is: how can I test to find out that the type of my_var_simple_1[0] is in fact my_simple_type? Is that at all possible?

Upvotes: 2

Views: 2709

Answers (3)

hpaulj
hpaulj

Reputation: 231385

In [7]: my_type_simple = np.dtype([('field_1', int), ('field_2', float)])
   ...: # An array using the above type
   ...: my_var_simple_1 = np.array([(1, 1), (2, 2)], dtype=my_type_simple)

The dtype command creates an dtype object, an instance of that class. It doesn't subclass dtype.

In [8]: type(my_type_simple)
Out[8]: numpy.dtype

The object created with np.array is a numpy array, ndarray. That's true regardless of the dtype.

In [11]: type(my_var_simple_1)
Out[11]: numpy.ndarray

For compound dtypes the type of an element is void. The type for each of your two fields is np.int64 and np.float64, but the combination is np.void.

In [12]: type(my_var_simple_1[0])
Out[12]: numpy.void

But we can access the dtype of the array or its element, and test that:

In [13]: my_var_simple_1.dtype
Out[13]: dtype([('field_1', '<i8'), ('field_2', '<f8')])
In [16]: my_var_simple_1[0].dtype
Out[16]: dtype([('field_1', '<i8'), ('field_2', '<f8')])

While type or isinstance can be useful in checking whether an object is ndarray as opposed to list or something else, the dtype is more useful when checking the properties of the array itself. (asking for alist.dtype will raise an error, since lists don't have such an attribute.) (Object dtype arrays are more like lists.)

Upvotes: 1

Diogo Silva
Diogo Silva

Reputation: 330

You are creating a custom numpy dtype. isinstance does not apply to the contents of an ndarray. For more info read this. For your problem you can do:

type(my_var_simple_1[0].item())

or like Or Y mentioned:

my_var_simple_1[0].dtype

Upvotes: 0

Or Y
Or Y

Reputation: 2118

Try that, see if it suits your needs:

my_var_simple_1[0].dtype == my_type_simple

Upvotes: 2

Related Questions