NumPy数组的就地类型转换

时间:2010-12-08 16:01:47

标签: python numpy

给定NumPy int32数组,如何将其转换为float32 到位?所以基本上,我想做

a = a.astype(numpy.float32)

不复制数组。它很大。

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

目前我在通过ctypes调用的C函数中进行转换。有没有办法在Python中执行此操作?

7 个答案:

答案 0 :(得分:153)

更新:此功能仅在可能的情况下避免复制,因此这不是此问题的正确答案。 unutbu's answer是正确的。


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

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

答案 1 :(得分:100)

您可以使用不同的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])

答案 2 :(得分:14)

您可以更改数组类型而不进行如下转换:

a.dtype = numpy.float32

但首先必须将所有整数更改为将被解释为相应的float的内容。执行此操作的一种非常缓慢的方法是使用python的struct模块,如下所示:

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

...应用于数组的每个成员。

但也许更快的方法是使用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

答案 3 :(得分:0)

阅读数据花费的时间

t1=time.time() ; V=np.load ('udata.npy');t2=time.time()-t1 ; print( t2 )

95.7923333644867

V.dtype

dtype('>f8')

V.shape

(3072, 1024, 4096)

**创建新数组**

t1=time.time() ; V64=np.array( V, dtype=np.double); t2=time.time()-t1 ; print( t2 )

1291.669689655304

简单的就地 numpy 转换

t1=time.time() ; V64=np.array( V, dtype=np.double); t2=time.time()-t1 ; print( t2 )

205.64322113990784

使用 astype

t1=time.time() ; V = V.astype(np.double) ; t2=time.time()-t1 ; print( t2 )

400.6731758117676

使用视图

t1=time.time() ; x=V.view(np.double);V[:,:,:]=x ;t2=time.time()-t1 ; print( t2 )

556.5982494354248

注意每次我清除变量。因此简单地让python处理转换是最有效的。

答案 4 :(得分:-1)

import numpy as np
arr_float = np.arange(10, dtype=np.float32)
arr_int = arr_float.view(np.float32)

使用view()和参数'dtype'更改数组。

答案 5 :(得分:-3)

{{1}}

答案 6 :(得分:-4)

使用此:

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)