numpy:如何快速转换数组类型

sho*_*nex 15 python numpy

我发现numpy数组的astype()方法效率不高.我有一个包含300万Uint8点的数组.将它乘以3x3矩阵需要2秒,但将结果从uint16转换为uint8需要另一秒.

更确切地说 :

    print time.clock()
    imgarray = np.dot(imgarray,  M)/255
    print time.clock()
    imgarray = imgarray.clip(0, 255)
    print time.clock()
    imgarray = imgarray.astype('B')
    print time.clock()
Run Code Online (Sandbox Code Playgroud)

点积和缩放需要2秒
剪辑需要200毫秒类型转换需要1秒

考虑到其他业务所花费的时间,我希望astype会更快.是否有更快的方式进行类型转换,或者在猜测类型转换不应该那么难时我错了吗?

编辑:目标是将最终的8位数组保存到文件中

unu*_*tbu 25

使用时imgarray = imgarray.astype('B'),您将获得数组的副本,强制转换为指定的类型.这需要额外的内存分配,即使你立即翻转imgarray指向新分配的数组.

如果您使用imgarray.view('uint8'),那么您将获得该数组的视图.这使用相同的数据,除了它被解释为uint8而不是imgarray.dtype.(np.dot返回一个uint32数组,所以后np.dot,imgarray是类型的uint32).

view然而,使用的问题是32位整数被视为4个8位整数,我们只关心最后8位的值.所以我们需要跳到每个第4个8位整数.我们可以用切片来做到这一点:

imgarray.view('uint8')[:,::4]

IPython的%timeit命令显示以这种方式显着加速:

In [37]: %timeit imgarray2 = imgarray.astype('B')
10000 loops, best of 3: 107 us per loop

In [39]: %timeit imgarray3 = imgarray.view('B')[:,::4]
100000 loops, best of 3: 3.64 us per loop
Run Code Online (Sandbox Code Playgroud)

  • 然后隐式地依赖于体系结构,因为使用哪个切片取决于字节顺序. (7认同)