使用 NumPy 将 ubyte [0, 255] 数组转换为浮点数组 [-0.5, +0.5] 的最快方法

Meh*_*dad 2 python arrays numpy normalization vectorization

问题在标题中,非常简单。

我有一个文件f,我正在从中读取一个ubyte数组:

arr = numpy.fromfile(f, '>u1', size * rows * cols).reshape((size, rows, cols))
max_value = 0xFF  # max value of ubyte
Run Code Online (Sandbox Code Playgroud)

目前我正在 3 次重新规范化数据,如下所示:

arr = images.astype(float)
arr -= max_value / 2.0
arr /= max_value
Run Code Online (Sandbox Code Playgroud)

由于数组有点大,这需要明显的几分之一秒。
如果我能在 1 或 2 次数据传递中做到这一点,那就太好了,因为我认为这会更快。

有什么方法可以让我执行“复合”矢量操作来减少传递次数?
或者,有没有其他方法可以让我加快速度?

小智 5

我做了:

ar = ar - 255/2.
ar *= 1./255
Run Code Online (Sandbox Code Playgroud)

看起来更快 :)

不,我计时了,它在我的系统上大约快两倍。它似乎ar = ar - 255/2.可以即时进行减法和类型转换。此外,似乎用标量除法没有优化:除法一次然后在数组上进行一堆乘法会更快。尽管额外的浮点运算可能会增加舍入误差。

正如评论中所指出的,numexpr可能是实现这一目标的真正快速而简单的方法。在我的系统上,它的速度快了两倍,但主要是由于numexpr使用了多个内核,而不是它只在阵列上进行一次传递。代码:

import numexpr
ar = numexpr.evaluate('(ar - 255.0/2.0) / 255.0')
Run Code Online (Sandbox Code Playgroud)