Numpy:多个值的矢量化

tau*_*ran 5 python numpy vectorization

想象一下,您有一个 RGB 图像并且想要处理每个像素:

import numpy as np
image = np.zeros((1024, 1024, 3))

def rgb_to_something(rgb):
    pass

vfunc = np.vectorize(rgb_to_something)
vfunc(image)
Run Code Online (Sandbox Code Playgroud)

vfunc现在应该得到每个 RGB 值。问题是 numpy 使数组变平,并且函数r0, g0, b0, r1, g1, b1, ...在它应该得到的时候得到 rgb0, rgb1, rgb2, ...。这可以以某种方式完成吗?

http://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html

也许通过事先将 numpy 数组转换为某种特殊的数据类型?

例如(当然不工作):

image = image.astype(np.float32)
import ctypes
RGB = ctypes.c_float * 3
image.astype(RGB)
ValueError: shape mismatch: objects cannot be broadcast to a single shape
Run Code Online (Sandbox Code Playgroud)

更新:这里的主要目的是提高效率。非矢量化版本可能看起来像这样:

import numpy as np
image = np.zeros((1024, 1024, 3))
shape = image.shape[0:2]
image = image.reshape((-1, 3))
def rgb_to_something((r, g, b)):
    return r + g + b
transformed_image = np.array([rgb_to_something(rgb) for rgb in image]).reshape(shape)
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 4

解决此类问题的简单方法是将整个数组传递给函数并在其中使用向量化习惯用法。具体来说,你rgb_to_something也可以写成

def rgb_to_something(pixels):
    return pixels.sum(axis=1)
Run Code Online (Sandbox Code Playgroud)

这比你的版本快大约 15 倍:

In [16]: %timeit np.array([old_rgb_to_something(rgb) for rgb in image]).reshape(shape)
1 loops, best of 3: 3.03 s per loop

In [19]: %timeit image.sum(axis=1).reshape(shape)
1 loops, best of 3: 192 ms per loop
Run Code Online (Sandbox Code Playgroud)

问题在于np.vectorize,当应用于大型数组时,它必然会产生大量的 Python 函数调用开销。