想象一下,你有一个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)
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
更新: 主要目的是提高效率。非矢量化版本可能看起来像这样:
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)
答案 0 :(得分:4)
解决此类问题的简单方法是将整个数组传递给函数,并在其中使用向量化的习语。具体来说,您的rgb_to_something
也可以写成
def rgb_to_something(pixels):
return pixels.sum(axis=1)
比你的版本快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
np.vectorize
的问题在于,当应用于大型数组时,它必然会产生大量的Python函数调用开销。
答案 1 :(得分:2)
在某些情况下,您可以使用Numexpr。例如:
import numpy as np
import numexpr
rgb = np.random.rand(3,1000,1000)
r,g,b = rgb
在这种情况下,numexpr甚至比“矢量化”numpy表达式快5倍。但是,并非所有功能都可以这样写。
%timeit r*2+g*3/b
10 loops, best of 3: 20.8 ms per loop
%timeit numexpr.evaluate("(r*2+g*3) / b")
100 loops, best of 3: 4.2 ms per loop