1

This seems like it should be super simple, but the answer is eluding me. I Have done a bunch of google-searches for the answer but don't feel like any of the results really answered my question, perhaps I'm just searching for the wrong thing? please help:

I am writing a function:

def cheese(array_like, *args, **kwargs):
    if dtype_of_(array_like) is float:
        return "macaroni"

The part dtype_of_(array_like) is float is obviously not functioning code, just something I wrote to give you an idea of what I am trying to accomplish.

What I need is to check whether the input is an iterable of floats (any type of float) or a float. Ie. the input "array_like" can be any iterable which can be converted to a numpy array or can even be a 0-dimensional array or a scalar.

I found this seemingly very similar question here, but I don't feel that it answered my question.

I also found this other similar question here, but this just concerns scalars, not arrays..

What I have done so far is to do:

def cheese(array_like, *args, **kwargs):
    np.array(array_like, copy=False).dtype == np.floating:
        return "macaroni"

But although this works it also gives me a deprecation warning:

DeprecationWarning: Converting np.inexact or np.floating to a dtype is deprecated. The current result is float64 which is not strictly correct. if np.array(array_like, copy=False).dtype == np.floating:

Vinzent
  • 1,070
  • 1
  • 9
  • 14

1 Answers1

2

I think you want np.issubdtype:

In [871]: np.issubdtype(np.array([1.23,3]).dtype, np.float64)
Out[871]: True
In [872]: np.issubdtype(np.array([1.23,3]).dtype, np.floating)
Out[872]: True
In [873]: np.issubdtype(np.array([1.23,3]).dtype, np.inexact)
Out[873]: True
In [874]: np.issubdtype(np.array([1,3]).dtype, np.floating)
Out[874]: False
In [875]: np.issubdtype(np.array(34.3).dtype, np.floating)
Out[875]: True

I haven't used this before, but remembered that release notes had some entries on testing for dtype.

https://numpy.org/doc/stable/release/1.20.0-notes.html#isinstance-dtype-np-dtype-and-not-type-dtype-is-not-np-dtype

https://numpy.org/doc/stable/release/1.19.0-notes.html#issubdtype-no-longer-interprets-float-as-np-floating

I haven't worked out all the details, but I think a major problem is that you are trying to test different kinds of things.

In [885]: type(np.array(1.23).dtype)
Out[885]: numpy.dtype[float64]
In [886]: type(np.floating)
Out[886]: type

The dtype of an array is a dtype object. But np.floating is actually a function, though only np.float64(12.23) can be used as such.

In [889]: np.float64.__mro__
Out[889]: 
(numpy.float64,
 numpy.floating,
 numpy.inexact,
 numpy.number,
 numpy.generic,
 float,
 object)

Functions like np.float64 can be used to both create numpy objects and arrays with a specific dtype, and to test. But == testing actually involves a bit of behind-the-scenes equivalence, that isn't obvious to python-level users.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • 2
    Just a small correction, `np.floating` and `np.float64` are both classes, the former being an abstract base class of the latter. Classes are *callables*, not functions exactly (though callables are all implemented by methods; in the case of classes it's `__new__` and `__init__`). Because it is abstract, calling `np.floating` will raise a `TypeError: cannot create 'numpy.floating' instances`. – BatWannaBe Sep 01 '21 at 19:02
  • This is exactly what I was looking for. Thanks a lot! – Vinzent Sep 02 '21 at 10:33