[英]Applying a function to a 3D array in numpy
我有一个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]
我应该怎么做才能将此功能应用于每个像素? (或2D数组的每个1D元素)
这个问题和我的一样。 因此,我首先尝试了它。
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不是为了提高速度
我将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笔记本并为每个测试重新启动了内核)
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
一种选择是转置numpy数组,将第三个轴交换为第一个轴,然后可以将函数直接应用于它:
my_sum(a.transpose(2,0,1))
#array([[ 3, 12],
# [21, 30]])
或将sum函数重写为:
my_sum = lambda x: x[..., 0] + x[..., 1] + x[..., 2]
my_sum(a)
#array([[ 3, 12],
# [21, 30]])
从numpy 1.12开始, vectorize
获得了signature
参数。 因此,您可以将其用作:
my_sum = lambda x: x[0] + x[1] + x[2]
vector_my_sum = np.vectorize(my_sum, signature='(i)->()') # vector to scalar
vector_my_sum(a)
不幸的是,这是一条比普通vectorize
慢得多的代码路径,后者在1.12中至少在C中运行for循环。
在我的机器上,使用numpy master
,这仅比apply_along_axis
快10%(尽管apply_along_axis
自1.12以来已大大改变了实现)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.