6

How do I convert a numpy array from type 'float64' to type 'float'? Specifically, how do I convert an entire array with dtype 'float64' to have dtype 'float'? Is this possible? The answer for scalars in the thought-to-be duplicate question above does not address my question.

Consider this:

>>> type(my_array[0])
<type 'numpy.float64'>

>>> # Let me try to convert this to 'float':
>>> new_array = my_array.astype(float)
>>> type(new_array[0])
<type 'numpy.float64'>

>>> # No luck.  What about this:
>>> new_array = my_array.astype('float')
>>> type(new_array[0])
<type 'numpy.float64'>

>>> # OK, last try:
>>> type(np.inf)
<type 'float'>
>>> # Yeah, that's what I want.
>>> new_array = my_array.astype(type(np.inf))
>>> type(new_array[0])
<type 'numpy.float64'>

If you're unsure why I might want to do this, see this question and its answers.

Community
  • 1
  • 1
dbliss
  • 8,060
  • 13
  • 43
  • 74
  • 4
    AFAIK `float` and `float64` are equivalent in numpy. – farenorth Sep 16 '15 at 04:28
  • @farenorth i'm guessing you didn't click to the linked question? – dbliss Sep 16 '15 at 04:29
  • 3
    possible duplicate of [Converting numpy dtypes to native python types](http://stackoverflow.com/questions/9452775/converting-numpy-dtypes-to-native-python-types) – tzaman Sep 16 '15 at 04:30
  • maybe this could help you? http://stackoverflow.com/questions/9452775/converting-numpy-dtypes-to-native-python-types – Reblochon Masque Sep 16 '15 at 04:30
  • @tzaman i think there's a subtle difference between the two questions. the answers there, for example, provide ways to convert individual scalars from `numpy` types to native python types. i want to convert the `dtype` of the `array` itself. but maybe this is impossible . . . – dbliss Sep 16 '15 at 04:33
  • I don't think it's possible. You're not looking for `float32` are you? – farenorth Sep 16 '15 at 04:39
  • @farenorth naa, that doesn't work for my purposes. the issue is that `inf - inf` raises a `RuntimeWarning` iff the `inf`s are of type `float32` or `float64` -- but not if they're of type `float`. i'm trying to avoid the warning. but i think `numpy` forces its `array`s to use its float types, specifically so that its warnings work. – dbliss Sep 16 '15 at 04:42
  • You can ignore errors or catch them using either warnings or np.errstate. – Alexander Huszagh Sep 16 '15 at 04:56
  • @AlexanderHuszagh yeah, i've been doing that. i don't want to ignore them, generally, and i thought switching types might obviate having to catch them. – dbliss Sep 16 '15 at 04:58
  • 1
    Well you can ignore specific warnings with np.errstate so you don't have to hide other warnings. – Alexander Huszagh Sep 16 '15 at 04:59
  • 1
    @AlexanderHuszagh ah, OK, yeah, that's cool. thanks. i'd been catching the warnings with the `warnings` module and `try`/`except` blocks, but `errstate` does seem much better. – dbliss Sep 16 '15 at 05:02
  • @dbliss, you can also try setting the dtype to be "object", since it then stores the data using Python types, as shown here, which solves the np.inf - np.inf error: https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#arrays-dtypes – Alexander Huszagh Sep 16 '15 at 05:12
  • 1
    @AlexanderHuszagh ah, that's a great option, too. but i think the best, clearest thing for me to do in my code is to carry out that subtraction in an `np.errstate` block. – dbliss Sep 16 '15 at 05:13

3 Answers3

8

Yes, actually when you use Python's native float to specify the dtype for an array , numpy converts it to float64. As given in documentation -

Note that, above, we use the Python float object as a dtype. NumPy knows that int refers to np.int_, bool means np.bool_ , that float is np.float_ and complex is np.complex_. The other data-types do not have Python equivalents.

And -

float_ - Shorthand for float64.

This is why even though you use float to convert the whole array to float , it still uses np.float64.

According to the requirement from the other question , the best solution would be converting to normal float object after taking each scalar value as -

float(new_array[0])

A solution that I could think of is to create a subclass for float and use that for casting (though to me it looks bad). But I would prefer the previous solution over this if possible. Example -

In [20]: import numpy as np

In [21]: na = np.array([1., 2., 3.])

In [22]: na = np.array([1., 2., 3., np.inf, np.inf])

In [23]: type(na[-1])
Out[23]: numpy.float64

In [24]: na[-1] - na[-2]
C:\Anaconda3\Scripts\ipython-script.py:1: RuntimeWarning: invalid value encountered in double_scalars
  if __name__ == '__main__':
Out[24]: nan

In [25]: class x(float):
   ....:     pass
   ....:

In [26]: na_new = na.astype(x)


In [28]: type(na_new[-1])
Out[28]: float                           #No idea why its showing float, I would have thought it would show '__main__.x' .

In [29]: na_new[-1] - na_new[-2]
Out[29]: nan

In [30]: na_new
Out[30]: array([1.0, 2.0, 3.0, inf, inf], dtype=object)
Anand S Kumar
  • 76,986
  • 16
  • 159
  • 156
  • 1
    clever answer, thanks. that said, i think the best answer -- at least for my purposes -- is to ignore the specific warning i'm getting with `float64`s using `np.errstate` -- see the comments above. – dbliss Sep 16 '15 at 05:07
  • I can answer a few of those. Numpy stores everything that it cannot find a suitable dtype for as "object", which is a Python object. In the case of your class X, it cannot see the float through class inheritance, so it chooses object. Since the type of the values in na_new are all floats, but the dtype is object, it means that everything is stored using a Pythonic type rather than the numpy float64. You can, however, perform math on object dtypes, which does provide some advantages. – Alexander Huszagh Sep 16 '15 at 05:11
3

You can create an anonymous type float like this

>>> new_array = my_array.astype(type('float', (float,), {}))
>>> type(new_array[0])
<type 'float'>
John La Rooy
  • 263,347
  • 47
  • 334
  • 476
0

This is not a good idea if you're trying to stay in numpy, but if you're done calculating and are moving out into native python, you can use

ndarray.tolist()

This converts arrays to lists (of lists) of appropriate native types. It also works on numpy scalar values.

naught101
  • 16,068
  • 19
  • 81
  • 128