NumPy数组就地转换

给定一个int32的NumPy数组,我该如何将它转换为float32 ? 所以基本上,我想这样做

 a = a.astype(numpy.float32) 

而不复制数组。 它很大。

这样做的原因是我有两个algorithm来计算a 。 其中一个返回一个int32数组,另一个返回一个float32数组(这是两个不同的algorithm所固有的)。 所有进一步的计算都假定a是一个float32的数组。

目前我在通过ctypes调用的C函数中进行转换。 有没有办法在Python中做到这一点?

您可以使用不同的dtype进行查看,然后就地复制到视图中:

 import numpy as np x = np.arange(10, dtype='int32') y = x.view('float32') y[:] = x print(y) 

产量

 array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.], dtype=float32) 

要显示转换是在原地,注意 x复制到y改变了x

 print(x) 

版画

 array([ 0, 1065353216, 1073741824, 1077936128, 1082130432, 1084227584, 1086324736, 1088421888, 1090519040, 1091567616]) 

更新:如果可以的话,这个函数只会避免复制,所以这不是这个问题的正确答案。 @ unutbu的答案是正确的。


 a = a.astype(numpy.float32, copy=False) 

numpy astype有一个复制标志。 为什么我们不应该使用它?

您可以更改数组types而不必像这样转换:

 a.dtype = numpy.float32 

但首先你必须改变所有的整数,将被解释为相应的浮动。 一个非常缓慢的方法是使用python的struct模块,如下所示:

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

…应用于arrays的每个成员。

但也许更快的方法是利用numpy的ctypeslib工具(我不熟悉)

– 编辑 –

由于ctypeslib似乎不起作用,那么我会继续使用典型的numpy.astype方法进行转换,但是要在您的内存限制内进行块大小处理:

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

…完成后更改dtype。

这是一个完成兼容dtypes的任务的函数(只适用于具有相同大小项目的dtypes)并且可以处理具有用户控制块大小的任意形状的数组:

 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 

a = np.subtract(a, 0., dtype=np.float32)

用这个:

 In [105]: a Out[105]: 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) Out[106]: 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)