Python Numpy成对应用函数并累积结果

Python Numpy成对应用函数并累积结果,python,function,numpy,list-comprehension,Python,Function,Numpy,List Comprehension,我想做一些简单的事情,但我还没有找到一个聪明的方法 假设我有一个包含3行的numpy数组,如下所示: import numpy as np a = np.array([[0.514, 0.966, 0.443, 0.95 , 0.524, 0.423, 0.75 , 0.463, 0.721, 0.089], [0.929, 0.014, 0.275, 0.521, 0.739, 0.612, 0.366, 0.469, 0.575, 0.533],

我想做一些简单的事情,但我还没有找到一个聪明的方法

假设我有一个包含3行的
numpy
数组,如下所示:

import numpy as np

a = np.array([[0.514, 0.966, 0.443, 0.95 , 0.524, 0.423, 0.75 , 0.463, 0.721, 0.089],
              [0.929, 0.014, 0.275, 0.521, 0.739, 0.612, 0.366, 0.469, 0.575, 0.533],
              [0.235, 0.084, 0.994, 0.713, 0.421, 0.851, 0.66 , 0.231, 0.699, 0.216]])
我想在每对行上应用以下函数,并累加结果,即(第0行与第1行)->(前一步的输出与第3行),依此类推:

def myfunc(x,y):
    return x**2 + y**2 - x*y
手动执行此操作可能类似于:

tmp1 = myfunc(a[0],a[1])
results = myfunc(tmp1,a[2])
现在,我想用一种智能的方式,对一个通用的
N(N=a.shape[0])
进行通用化

我尝试过基于列表理解的方法,但我不能将其推广到任何N


编辑1:

N=4的示例:

tmp1 = myfunc(a[0],a[1])
tmp2 = myfunc(tmp1,a[2])
results = myfunc(tmp2,a[3])

以下是一种简单的解决方法,在第一个维度(即轴-0)上使用
for
循环:


通过手动呼叫进行健康检查
N=4的情况下的结果
注意:这应该推广到任何
N
,其中
N=arr.shape[0]
。另外,请注意,由于计算是顺序的,因此没有简单的并行方法。

是函数的简化版本,以及一个突出显示操作的
A

In [344]: def myfunc(x,y): 
     ...:     return 2*x + y 
     ...: a = np.eye(5)                                                              
In [345]: a                                                                          
Out[345]: 
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])
In [346]: res = myfunc(a[0],a[1])                                                    
In [347]: res                                                                        
Out[347]: array([2., 1., 0., 0., 0.])
In [348]: for i in a[2:]: 
     ...:     res = myfunc(res,i) 
     ...:                                                                            
In [349]: res                                                                        
Out[349]: array([16.,  8.,  4.,  2.,  1.])
Python有一个
reduce
函数来重复地将函数应用于列表。在Py3中,这在
functools
中:

In [355]: functools.reduce(myfunc, a)                                                
Out[355]: array([16.,  8.,  4.,  2.,  1.])
或从零开始,并应用于整个阵列:

In [357]: res = np.zeros(a.shape[1])                                                 
In [358]: for i in a: 
     ...:     res = myfunc(res,i) 
     ...:                                                                            
In [359]: res                                                                        
Out[359]: array([16.,  8.,  4.,  2.,  1.])
要保存中间结果,请执行以下操作:

In [361]: res = [np.zeros(a.shape[1])] 
     ...: for i in a: 
     ...:     temp = myfunc(res[-1],i) 
     ...:     res.append(temp)                                                                            
In [362]: res                                                                        
Out[362]: 
[array([0., 0., 0., 0., 0.]),
 array([1., 0., 0., 0., 0.]),
 array([2., 1., 0., 0., 0.]),
 array([4., 2., 1., 0., 0.]),
 array([8., 4., 2., 1., 0.]),
 array([16.,  8.,  4.,  2.,  1.])]
这就是累积的概念
numpy
ufunc
既有
reduce
又有
acculate
,如果能用它们编写
myfunc
,速度会更快。但这在一般情况下不起作用

In [363]: np.add.accumulate(a,axis=0)                                                
Out[363]: 
array([[1., 0., 0., 0., 0.],
       [1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0.],
       [1., 1., 1., 1., 0.],
       [1., 1., 1., 1., 1.]])

对循环使用
。或者使用
functools.reduce
函数(py3)
numpy
ufunc
还有一个
reduce
方法。嘿。for循环可以,但我尝试过使用for循环,但我也没有找到一种方法来概括它。请澄清您想要更高的N、4或5等。请参阅编辑1 for N=4这正是我所需要的。
In [357]: res = np.zeros(a.shape[1])                                                 
In [358]: for i in a: 
     ...:     res = myfunc(res,i) 
     ...:                                                                            
In [359]: res                                                                        
Out[359]: array([16.,  8.,  4.,  2.,  1.])
In [361]: res = [np.zeros(a.shape[1])] 
     ...: for i in a: 
     ...:     temp = myfunc(res[-1],i) 
     ...:     res.append(temp)                                                                            
In [362]: res                                                                        
Out[362]: 
[array([0., 0., 0., 0., 0.]),
 array([1., 0., 0., 0., 0.]),
 array([2., 1., 0., 0., 0.]),
 array([4., 2., 1., 0., 0.]),
 array([8., 4., 2., 1., 0.]),
 array([16.,  8.,  4.,  2.,  1.])]
In [363]: np.add.accumulate(a,axis=0)                                                
Out[363]: 
array([[1., 0., 0., 0., 0.],
       [1., 1., 0., 0., 0.],
       [1., 1., 1., 0., 0.],
       [1., 1., 1., 1., 0.],
       [1., 1., 1., 1., 1.]])