如何在Lambda函数中使用numpy apply_over_axes?

时间:2018-08-12 13:51:33

标签: python numpy

如何将numpy apply_over_axes与lambda函数一起使用?

这个:

import pandas as pd
import numpy as np

a = np.arange(6).reshape(2,3)

print(a)

>>[[0 1 2]
>> [3 4 5]]

def method_name(x,axis=0):
    return lambda x: print(x) or x ** 2
np.apply_over_axes(method_name, a,0)

导致:

AttributeError: 'function' object has no attribute 'ndim'

method_name声明中省略任何参数将导致:

TypeError: method_name() takes 0 positional arguments but 2 were given

1 个答案:

答案 0 :(得分:1)

我已经在其他apply功能上提供了更多帮助,因此不得不查看文档和实验。

但是看看当我们调用您的函数时会发生什么:

In [185]: method_name(a,0)
Out[185]: <function __main__.method_name.<locals>.<lambda>(x)>

它返回了lambda函数。 apply期望函数调用返回一个数组,因此抱怨它没有ndim

更改功能:

def method_name(x,axis=0):
    l = lambda x: print(x) or x ** 2
    return l(x)

现在可以使用了

In [187]: np.apply_over_axes(method_name, a,0)
[[0 1 2]
 [3 4 5]]
Out[187]: 
array([[ 0,  1,  4],
       [ 9, 16, 25]])

因此它曾经调用method_name,并传递了a。您的lambda打印a(作为副作用)并返回其平方。

如果我们提供2个轴值怎么办?

In [188]: np.apply_over_axes(method_name, a,[0,1])
[[0 1 2]
 [3 4 5]]
[[ 0  1  4]
 [ 9 16 25]]
Out[188]: 
array([[  0,   1,  16],
       [ 81, 256, 625]])

平方两次!对于第二次呼叫,它作为x传递了第一次呼叫的结果。轴不必是唯一的或顺序是:np.apply_over_axes(method_name, a,[0,1,0,1])

文档使用np.sum作为函数进行了说明,并使用多个轴演示了sum的等效性。像sum之类的函数最初仅使用一个轴值。在这种情况下,此apply_over_axes将是重复总和的便捷方式(而不是np.sum(np.sum(a, 0),0))。但是现在像这样的函数列出了清单,因此对apply_over_axes函数的需求减少了。


cumsum可能比sum更好,因为它返回尺寸数组,并且不采用多个轴:

垂直求和:

In [210]: np.cumsum(a,0)
Out[210]: 
array([[0, 1, 2],
       [3, 5, 7]])

并再次跨列:

In [211]: np.cumsum(_,1)
Out[211]: 
array([[ 0,  1,  3],
       [ 3,  8, 15]])

apply做同样的事情:

In [212]: np.apply_over_axes(np.cumsum, a, [0])
Out[212]: 
array([[0, 1, 2],
       [3, 5, 7]])

In [213]: np.apply_over_axes(np.cumsum, a, [0,1])
Out[213]: 
array([[ 0,  1,  3],
       [ 3,  8, 15]])

或另一个:

In [229]: l = lambda a, axis: np.add.accumulate(a**2, axis)

In [230]: l(l(a,0),1)
Out[230]: 
array([[   0,    1,   17],
       [  81,  370, 1211]])

In [231]: np.apply_over_axes(l, a, [0,1])
Out[231]: 
array([[   0,    1,   17],
       [  81,  370, 1211]])

在函数缩小尺寸的情况下,例如reduce

In [236]: rl = lambda a, axis: np.add.reduce(a**2, axis)

In [237]: np.apply_over_axes(rl, a, [0,1])
Out[237]: array([[1211]])

apply_over_axes在跟踪维度方面比嵌套调用做得更好:

In [239]: rl(rl(a,0),0)
Out[239]: 1211
In [240]: rl(rl(a,0)[None,:],1)
Out[240]: array([1211])