python - 如何使用 numpy 有效地将函数应用于第三维数组?

标签 python arrays numpy multidimensional-array vectorization

我想将任意函数应用于 3d-ndarray 作为元素,它使用(3维)数组作为其参数并返回标量。因此,我们应该得到 2d-Matrix。

例如)伪代码

A = [[[1,2,3],[4,5,6]],
     [[7,8,9],[10,11,12]]]
A.apply_3d_array(sum) ## or apply_3d_array(A,sum) is Okey.
>> [[6,15],[24,33]]

我知道可以使用 ndarray.shape 函数进行循环,但正如官方文档所述,直接索引访问效率低下。 还有比使用循环更有效的方法吗?

def chromaticity(pixel):
    geo_mean = math.pow(sum(pixel),1/3)
    return map(lambda x: math.log(x/geo_mean),pixel ) 

最佳答案

鉴于函数实现,我们可以使用NumPy ufuncs对其进行向量化它将一次性对整个输入数组 A 进行操作,从而避免使用不支持数组矢量化的 math 库函数。在此过程中,我们还将引入非常高效的矢量化工具:NumPy broadcasting 。所以,我们会有一个像这样的实现 -

np.log(A/np.power(np.sum(A,2,keepdims=True),1/3))

示例运行和验证

没有 lamdba 构造并引入 NumPy 函数而不是 math 库函数的函数实现看起来像这样 -

def chromaticity(pixel): 
    geo_mean = np.power(np.sum(pixel),1/3) 
    return np.log(pixel/geo_mean)

使用迭代实现运行示例 -

In [67]: chromaticity(A[0,0,:])
Out[67]: array([-0.59725316,  0.09589402,  0.50135913])

In [68]: chromaticity(A[0,1,:])
Out[68]: array([ 0.48361096,  0.70675451,  0.88907607])

In [69]: chromaticity(A[1,0,:])
Out[69]: array([ 0.88655887,  1.02009026,  1.1378733 ])

In [70]: chromaticity(A[1,1,:])
Out[70]: array([ 1.13708257,  1.23239275,  1.31940413])    

使用建议的矢量化实现运行示例 -

In [72]: np.log(A/np.power(np.sum(A,2,keepdims=True),1/3))
Out[72]: 
array([[[-0.59725316,  0.09589402,  0.50135913],
        [ 0.48361096,  0.70675451,  0.88907607]],

       [[ 0.88655887,  1.02009026,  1.1378733 ],
        [ 1.13708257,  1.23239275,  1.31940413]]])

运行时测试

In [131]: A = np.random.randint(0,255,(512,512,3)) # 512x512 colored image

In [132]: def org_app(A):
     ...:     out = np.zeros(A.shape)     
     ...:     for i in range(A.shape[0]):
     ...:         for j in range(A.shape[1]):
     ...:             out[i,j] = chromaticity(A[i,j])
     ...:     return out
     ...: 

In [133]: %timeit org_app(A)
1 loop, best of 3: 5.99 s per loop

In [134]: %timeit np.apply_along_axis(chromaticity, 2, A) #@hpaulj's soln
1 loop, best of 3: 9.68 s per loop

In [135]: %timeit np.log(A/np.power(np.sum(A,2,keepdims=True),1/3))
10 loops, best of 3: 90.8 ms per loop

这就是为什么在使用数组对事物进行矢量化时始终尝试插入 NumPy funcs 并一次性处理尽可能多的元素!

关于python - 如何使用 numpy 有效地将函数应用于第三维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39308835/

相关文章:

python - IBM WebSphere Application Server wsadmin 在脚本中仅返回 6 个结果中的第一个结果

python - 使用tkinter在python中进行gui编程时出错

python - 如何使用 Pybrain 预测新数据?

javascript - 替换数组 : "hh:mm" to "H" 中的小时项目

c++ - 如何为我的数组选择更大的数据类型?

c - 覆盖 C 数组中的空字符

python - 平均忽略 NumPy 数组中列的 NaN,而不使用 numpy.nanmean

python - NetworkX 访问具有多个节点属性的节点

Python:打印 Pandas dataframe 返回 numpy.ndarray 属性错误

python - 使用指定索引 reshape 数组