34

I have different types of data. most of them are int and sometimes float. The int is different in size so 8/ 16/ 32 bits are the sizes.
For this situation I'm creating a numerical type converter. therefore i check the type by using isinstance(). This because I have read that isinstance() is less worse than type().

The point is that a lot of data i get is numpy arrays. I use spyder as IDE and then i see by the variables also a type. but when i type isinstance(var,'type i read') i get False.

I did some checks:

a = 2.17 
b = 3 
c = np.array(np.random.rand(2, 8))
d = np.array([1])

for there isinstance(var,type) i get:

isinstance(a, float)
True
isinstance(b, int)
True
isinstance(c, float)  # or isinstance(c, np.float64)
False
isinstance(d, int)  # or isinstance(c, np.int32)
False

c and d are True when i ask

isinstance(c, np.ndarray)
True
isinstance(d, np.ndarray)
True

i can check with step in the ndarray by

isinstance(c[i][j], np.float64)
True
isinstance(d[i], np.int32)
True

but this means that for every dimension i have to add a new index otherwise it is False again. I can check there type with dtype like c.dtype == 'float64'...

Oke so for what i have find and tried... My questions are basically:

  • how is the var.dtype method compared to isinstance() and type() (worst/ better etc)?
  • if var.dtype is even worse as isinstance() is there some method in the isinstance() without all the manual indexing? (autoindexing etc)?
5
  • Where do you have this data with different integer sizes? As Python objects, numpy arrays, files? You may need to give more context for the use of the numerical type converter. Commented Oct 28, 2016 at 21:52
  • mostly multichannel audio files Commented Oct 30, 2016 at 13:02
  • And how do you intend to convert the data type? Commented Oct 30, 2016 at 15:45
  • from the int type/ numpy.intXX type change to (numpy.)float(64) and scale down with the integer size. So everything is -1 min to +1 max Commented Oct 30, 2016 at 17:21
  • I added a note on np.can_cast and .astype to my answer. Commented Oct 30, 2016 at 17:51

5 Answers 5

43

An array is an object of type np.ndarray. Its values or elements are stored in a data buffer, which can be thought of as a contiguous block of memory bytes. The bytes in the data buffer do not have a type, because they are not Python objects.

The array has a dtype parameter, which is used to interpret those bytes. If dtype is int32 (there are various synonyms), 4 bytes are interpreted as an integer. Accessing an element, say c[0] gives a new object that depends on the dtype, e.g. an object type np.int32.

c[0].item will give an Python object of the corresponding type:

In [2102]: c=np.array([1])
In [2103]: c.dtype
Out[2103]: dtype('int32')
In [2104]: type(c)
Out[2104]: numpy.ndarray
In [2105]: type(c[0])
Out[2105]: numpy.int32
In [2107]: c[0].item()
Out[2107]: 1
In [2108]: type(c[0].item())
Out[2108]: int

(And c[0].dtype is the same as for c.dtype; you don't need to index individual elements of an array to check their dtype).

The same 4 bytes of this array can be viewed as dtype int8 - a single byte integer.

In [2112]: c.view('b')
Out[2112]: array([1, 0, 0, 0], dtype=int8)

A single element of this alternate view is np.int8, but when I take item(), I get a Python integer. There isn't a int8 Python numeric type.

In [2113]: type(c.view('b')[0])
Out[2113]: numpy.int8
In [2115]: type(c.view('b')[0].item())
Out[2115]: int

A list contains pointers to Python objects, each of which has a type. So does an array of dtype=object. But the common numeric array does not contain Python integers or floats. It has a data buffer that can interpreted in various ways according to the dtype. Python integers don't come in different sizes, at least not to the same extent as numpy dtypes.

So the isinstance and type() stuff does not apply to the contents of an ndarray.

====================

From the comments I gather you are trying to convert integer arrays to float. You aren't converting scalars. If so then dtype is all that matters; an array always has a dtype. It's unclear whether you are ok with casting a np.float32 to np.float64.

I'd suggest studying, and experimenting with the np.can_cast function and the x.astype method.

x.astype(np.float64, copy=False)

for example will convert all int dtypes to float, without copying the ones that are already float64. It may copy and convert np.float32 ones.

Look also at the casting parameter of these functions.

===========================

I found in scipy.optimize.minimize another testing tool

In [156]: np.typecodes
Out[156]: 
{'All': '?bhilqpBHILQPefdgFDGSUVOMm',
 'AllFloat': 'efdgFDG',
 'AllInteger': 'bBhHiIlLqQpP',
 'Character': 'c',
 'Complex': 'FDG',
 'Datetime': 'Mm',
 'Float': 'efdg',
 'Integer': 'bhilqp',
 'UnsignedInteger': 'BHILQP'}

It can be used to check for integers with:

if x0.dtype.kind in np.typecodes["AllInteger"]:
    x0 = np.asarray(x0, dtype=float)
Sign up to request clarification or add additional context in comments.

Comments

9

To directly answer the question, you can do this:

isinstance(arr.flat[0], np.floating)

  • .flat will collapse any number of dimensions down, so you can then access the 0th element easily.
  • np.floating will match any numpy float type

1 Comment

This assumes the array has a first element. It might not - arrays can have 0 elements. This is strictly inferior to a dtype check.
5

A slight variation from @rasen58 and @hpaulj:

To check if an np array, c, has elements of type float, c.dtype == np.floating works for me.

4 Comments

FWIW, when I tried this I got /usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:79: DeprecationWarning: Converting 'np.inexact' or 'np.floating' to a dtype is deprecated. The current result is 'float64' which is not strictly correct.
However using c.dtype == np.double did work for me. More information on numpy type names here: numpy.org/doc/stable/user/basics.types.html
For me the warning @CraigReynolds describes disappears when I test for c.dtype == float instead of c.dtype == np.floating I'm not quite sure how equivalent those tests are, but in my case I get the expected results.
Thanks @Malo Pocheau. I was so young and naive way back then, ~4 month ago, being new to Python, numpy, deep learning...
1

All entries in a numpy array are of the same type. The numpy type and the Python type are not the same thing. This can be a bit confusing, but the type numpy refers to is more like the types used by languages like C - you might say more low level closer the the machine.

You can not say which type is better, because it would be like comparing apple and oranges.

1 Comment

You should say all entries ... are of the same dtype, and numpy dtype. The type of an array is ndarray, regardless of its dtype.
-1

I wrote a small wrapper which works basically like isinstance and accepts an object o and a class (or tuple of classes) c. The only difference is if isinstance(o, np.ndarray) is True, o.flat[0] is checked against a mapped numpy data type (see the dict c2np) I mostly work with bool, int, float, str but this list can be changed / extended. Note that np.integer and np.floating are collections of most / all? available numpy subtypes as np.int8, np.unit16, ...

def np_isinstance(o, c):
    c2np = {bool: np.bool, int: np.integer, float: np.floating, str: np.str}

    if isinstance(o, np.ndarray):
        c = (c2np[cc] for cc in c) if isinstance(c, tuple) else c2np[c]
        return isinstance(o.flat[0], c)

    else:
        return isinstance(o, c)

Some examples:

# Like isinstance if o is not np.ndarray
np_isinstance(('this', 'that'), tuple)  # True
np_isinstance(4.4, int)                 # False
np_isinstance(4.4, float)               # True

#
np_isinstance(np.ones(4, dtype=int), int)    # True
np_isinstance(np.ones(4, dtype=int), float)  # False
np_isinstance(np.full((4, 4), 'bert'), str)  # True

1 Comment

This fails for bool, and is strictly inferior to a dtype check.

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.