我发现numpy数组的astype()方法效率不高。我有一个包含的数组 Uint8点300万。将它乘以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()
点积和缩放需要2秒 削减需要200毫秒 类型转换需要1秒
考虑到其他操作所花费的时间,我希望astype
更快。
是否有更快的方式进行类型转换,或者在猜测类型转换不应该那么难时我错了吗?
编辑:目标是将最终的8位数组保存到文件
答案 0 :(得分: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