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)