【发布时间】:2017-08-20 20:37:17
【问题描述】:
我有一个 3D numpy.ndarray(想想一个带有 RGB 的图像),比如
a = np.arange(12).reshape(2,2,3)
'''array(
[[[ 0, 1, 2], [ 3, 4, 5]],
[[ 6, 7, 8], [ 9, 10, 11]]])'''
还有一个处理列表输入的函数;
my_sum = lambda x: x[0] + x[1] + x[2]
如何将此函数应用于每个像素?(或二维数组的每个一维元素)
我尝试过的
np.apply_along_axis
This question 和我的一样。所以,我先试了一下。
np.apply_along_axis(my_sum, 0, a.T).T #EDIT np.apply_along_axis(my_sum, -1, a) is better
起初,我以为这是解决方案,但这太慢了,因为np.apply_along_axis is not for speed
np.vectorize
我将 np.vetorize 应用于 my_func。
vector_my_func = np.vectorize(my_sum)
但是,我什至不知道如何调用这个矢量化函数。
vector_my_func(0,1,2)
#=> TypeError: <lambda>() takes 1 positional argument but 3 were given
vector_my_func(np.arange(3))
#=> IndexError: invalid index to scalar variable.
vector_my_func(np.arange(12).reshape(4,3))
#=> IndexError: invalid index to scalar variable.
vector_my_func(np.arange(12).reshape(2,2,3))
#=> IndexError: invalid index to scalar variable.
我完全不知道该怎么做。
编辑
建议方法的基准测试结果。 (每次测试使用 jupyter notebook 并重启内核)
a = np.ones((1000,1000,3))
my_sum = lambda x: x[0] + x[1] + x[2]
my_sum_ellipsis = lambda x: x[..., 0] + x[..., 1] + x[..., 2]
vector_my_sum = np.vectorize(my_sum, signature='(i)->()')
%timeit np.apply_along_axis(my_sum, -1, a)
#1 loop, best of 3: 3.72 s per loop
%timeit vector_my_sum(a)
#1 loop, best of 3: 2.78 s per loop
%timeit my_sum(a.transpose(2,0,1))
#100 loops, best of 3: 12 ms per loop
%timeit my_sum_ellipsis(a)
#100 loops, best of 3: 12.2 ms per loop
%timeit my_sum(np.moveaxis(a, -1, 0))
#100 loops, best of 3: 12.2 ms per loop
【问题讨论】:
-
vectorize在这里帮不了你,遗憾的是,它模拟的是ufunc,而不是gufunc -
这三个选项的测试数据有多大?
-
我添加了我在基准测试中实际所做的。
-
对于那些在发表评论之前看到这个基准的人 基准设计很糟糕,没有达到我希望他们做的事情。现在,我相信它已经修复了。
-
感谢您的指出。基准测试现在不包括 my_sum 的创建。
标签: python numpy image-processing matrix