Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is numpy.dtype('float64') special?

Tags:

python

numpy

Can someone explain the logic behind the output of the following script?

import numpy
if(numpy.dtype(numpy.float64) == None):
    print "Surprise!!!!"

Thanks :)

like image 230
Troels Blum Avatar asked Mar 22 '14 07:03

Troels Blum


People also ask

What does Dtype float64 mean?

By setting dtype to float64 you are just telling the computer to read that memory as float64 instead of actually converting the integer numbers to floating point numbers.

What does float64 mean in Python?

Python float values are represented as 64-bit double-precision values. 1.8 X 10308 is an approximate maximum value for any floating-point number. If it exceeds or exceeds the max value, Python returns an error with string inf (infinity).

What is difference between Numpy float64 and float?

float64 are numpy specific 32 and 64-bit float types. Thus, when you do isinstance(2.0, np. float) , it is equivalent to isinstance(2.0, float) as 2.0 is a plain python built-in float type... and not the numpy type. isinstance(np.


2 Answers

Looks like an unfortunate accident: someone decided that dtype(None) would "default" to float (though dtype() is an error). Then someone else wrote dtype.__eq__ such that it converts its second argument to a dtype before comparing. So dtype(float) == None is dtype(float) == dtype(None) which is true.

You can see a comment in the source code here: descriptor.c#L1217

  • Get typenum from an object -- None goes to NPY_DEFAULT_TYPE

And of course NPY_DEFAULT_TYPE is float (at least usually).

As for the __eq__ operator, it's here: descriptor.c#L3317. It does what I outlined:

if (!PyArray_DescrCheck(other)) {
    if (PyArray_DescrConverter(other, &new) == NPY_FAIL) {
        return NULL;
    }
}

So that's a conversion from whatever is on the right-hand side of == to a dtype object, via the converter function mentioned before, which turns None into dtype(float).

Edit: I found this pretty interesting and it seems like an accident, so I created a patch and submitted to the maintainers: https://github.com/numpy/numpy/pull/4532 .

like image 186
John Zwinck Avatar answered Sep 21 '22 21:09

John Zwinck


if you want to compare an arbitrary object against exactly None in python you need to use:

object is None

Like in this case any object may override its comparison operator to not do what you are expecting.

As for why, dtype('float64') is equivalent to None in the context of dtypes in the same way dtypes are equivalent to typestrings

np.dtype('i4') == 'i4'
True

Equality is not identity.

As for why dtype(None) == dtype('float64'), many functions in numpy have dtype=None keyword arguments. In most cases this means default dtype which is dtype(None). An example is np.zeros. But there are exceptions, e.g. when the dtype can be inferred from the arguments, like in the case of np.arange(10) where the default dtype will be of integer type (np.intp I think).

like image 44
jtaylor Avatar answered Sep 25 '22 21:09

jtaylor