NumPy/SciPy中的广义累积函数是什么?

20
numpy或者scipy(或其他库)中是否有一种函数可以将cumsum和cumprod的思想推广到任意函数上。例如,考虑以下(理论上的)函数:
cumf( func, array) 

func是一个接受两个浮点数并返回一个浮点数的函数。特殊情况:

lambda x,y: x+y 

并且
lambda x,y: x*y 

累计求和和累计乘积分别是cumsum和cumprod。例如,如果:
func = lambda x,prev_x: x^2*prev_x 

我将其应用于:

cumf(func, np.array( 1, 2, 3) )

I would like

np.array( 1, 4, 9*4 )

我认为这是一个很好的想法,但我认为更规范的做法是定义 func = lambda x, y: x+y(两个无关的参数),并让累积概念“找出”x和y实际上是序列的连续元素。 - heltonbiker
那更多是为了人类读者而言的 ;) - Cam.Davidson.Pilon
2个回答

14

在使用Numpy 1.20.1 (Python 3.9.1)时,上述的ValueError仍然存在bug。

幸运的是,我们发现了一种解决方法,可以使用强制转换:

https://groups.google.com/forum/#!topic/numpy/JgUltPe2hqw

import numpy as np
uadd = np.frompyfunc(lambda x, y: x + y, 2, 1)
uadd.accumulate([1,2,3], dtype=object).astype(int)
# array([1, 3, 6])

请注意,由于自定义操作依赖于对象类型,它无法从numpy的高效内存管理中获得益处。因此,对于非常大的数组,需要将其转换为对象类型的操作可能比不需要转换的操作慢。


12

NumPy的ufuncs拥有accumulate()函数:

In [22]: np.multiply.accumulate([[1, 2, 3], [4, 5, 6]], axis=1)
Out[22]: 
array([[  1,   2,   6],
       [  4,  20, 120]])

很不幸,对于一个使用frompyfunc()处理过的Python函数,调用accumulate()将会导致奇怪的错误:

In [32]: uadd = np.frompyfunc(lambda x, y: x + y, 2, 1)

In [33]: uadd.accumulate([1, 2, 3])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

ValueError: could not find a matching type for <lambda> (vectorized).accumulate, 
            requested type has type code 'l'

使用Python 2.7.3和NumPy 1.6.1。


啊,但我想要一个NumPy数组作为输出。 - Cam.Davidson.Pilon
这里不需要使用 np.array。Numpy可以很好地操作您的列表,但是好的答案(+1)。 - mgilson
虽然使用lambda函数失败了,但我可以用ufuncs重新创建所需的函数。这正是我需要的。感谢您向我介绍ufuncs和accumulate! - Cam.Davidson.Pilon
@Cam.Davidson.Pilon 现在你已经通过ufuncs和accumulate找出了如何实现它,请发布一段可工作的代码作为你自己的答案,或编辑问题,以便其他人也能受益。谢谢! - heltonbiker
@Cam.Davidson.Pilon:是的,那正是我遇到的 Bug。 - NPE
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接