如何将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
答案 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])