Take the 2-minute tour ×

Given a NumPy array of int32, how do I convert it to float32 in place? So basically, I would like to do

a = a.astype(numpy.float32)

without copying the array. It is big.

The reason for doing this is that I have two algorithms for the computation of a. One of them returns an array of int32, the other returns an array of float32 (and this is inherent to the two different algorithms). All further computations assume that a is an array of float32.

Currently I do the conversion in a C function called via ctypes. Is there a way to do this in Python?

share|improve this question
Using ctypes is as much "in Python" as using numpy. :) –  Karl Knechtel Dec 8 '10 at 16:40
@Karl: No, because I have to code and compile the C function myself. –  Sven Marnach Dec 8 '10 at 16:42
Oh, I see. I think you're probably SOL on this one. –  Karl Knechtel Dec 8 '10 at 16:45
@Andrew: There are many ways to tell if it returns a copy. One of them is to read the documentation. –  Sven Marnach Jan 22 '11 at 20:24
In-place simply means "using the same memory as the original array". Have a look at the accepted answer -- the last part shows that the new values indeed have overwritten the same memory. –  Sven Marnach Feb 13 '12 at 15:02

4 Answers 4

up vote 35 down vote accepted

How about:

In [1]: x=np.arange(10)

In [2]: x.dtype
Out[2]: dtype('int32')

In [3]: y=x.view('float32')

In [4]: y[:]=x

In [5]: y

(To show the conversion was in-place):

In [6]: x
array([         0, 1065353216, 1073741824, 1077936128, 1082130432,
       1084227584, 1086324736, 1088421888, 1090519040, 1091567616])
share|improve this answer
Great, thanks! It's obvious once someone pointed it out. –  Sven Marnach Dec 9 '10 at 9:19
Note for those (like me) that want conversion between dtype of different byte-size (e.g. 32 to 16 bits): This method fails because y.size <> x.size. Logical once you think about it :-( –  Juh_ Jun 12 '12 at 9:17
a = a.astype(numpy.float32, copy=False)

numpy astype has a copy flag. Why shouldn't we use it ?

share|improve this answer
Once this parameter is supported in a NumPy release, we could of course use it, but currently it's only available in the development branch. And at the time I asked this question, it didn't exist at all. –  Sven Marnach May 17 '12 at 19:08
@SvenMarnach It is now supported, at least in my version (1.7.1). –  PhilMacKay Aug 27 '13 at 20:09
It seems to work perfectly in python3.3 with the latest numpy version. –  CHM Oct 10 '13 at 21:41

You can change the array type without converting like this:

a.dtype = numpy.float32

but first you have to change all the integers to something that will be interpreted as the corresponding float. A very slow way to do this would be to use python's struct module like this:

def toi(i):
    return struct.unpack('i',struct.pack('f',float(i)))[0]

...applied to each member of your array.

But perhaps a faster way would be to utilize numpy's ctypeslib tools (which I am unfamiliar with)

- edit -

Since ctypeslib doesnt seem to work, then I would proceed with the conversion with the typical numpy.astype method, but proceed in block sizes that are within your memory limits:

a[0:10000] = a[0:10000].astype('float32').view('int32')

...then change the dtype when done.

Here is a function that accomplishes the task for any compatible dtypes (only works for dtypes with same-sized items) and handles arbitrarily-shaped arrays with user-control over block size:

import numpy

def astype_inplace(a, dtype, blocksize=10000):
    oldtype = a.dtype
    newtype = numpy.dtype(dtype)
    assert oldtype.itemsize is newtype.itemsize
    for idx in xrange(0, a.size, blocksize):
        a.flat[idx:idx + blocksize] = \
            a.flat[idx:idx + blocksize].astype(newtype).view(oldtype)
    a.dtype = newtype

a = numpy.random.randint(100,size=100).reshape((10,10))
print a
astype_inplace(a, 'float32')
print a
share|improve this answer
Thanks for your answer. Honestly, I don't think this is very useful for big arrays -- it is way too slow. Reinterpreting the data of the array as a different type is easy -- for example by calling a.view(numpy.float32). The hard part is actually converting the data. numpy.ctypeslib only helps with reinterpreting the data, not with actually converting it. –  Sven Marnach Dec 8 '10 at 17:39
ok. I wasn't sure what your memory/processor limitations were. See my edit. –  Paul Dec 8 '10 at 18:16
Thanks for the update. Doing it blockwise is a good idea -- probably the best you can get with the current NumPy interface. But in this case, I will probably stick to my current ctypes solution. –  Sven Marnach Dec 8 '10 at 20:21

Use this:

In [105]: a
array([[15, 30, 88, 31, 33],
       [53, 38, 54, 47, 56],
       [67,  2, 74, 10, 16],
       [86, 33, 15, 51, 32],
       [32, 47, 76, 15, 81]], dtype=int32)

In [106]: float32(a)
array([[ 15.,  30.,  88.,  31.,  33.],
       [ 53.,  38.,  54.,  47.,  56.],
       [ 67.,   2.,  74.,  10.,  16.],
       [ 86.,  33.,  15.,  51.,  32.],
       [ 32.,  47.,  76.,  15.,  81.]], dtype=float32)
share|improve this answer
Are you sure that is not a copy? Can you check it and explain a little bit more? –  Michele d'Amico Feb 19 at 16:05

Your Answer


