用于非均匀间距的NumPy或SciPy导数函数?

9

我想知道numpy或scipy库中是否有一种方法可以找到具有非均匀间距的值列表的数值导数。这个想法是将对应于这些值的时间戳输入进去,然后使用时间戳来找到数值导数。

5个回答

7
你可以使用numpy创建自己的函数。对于使用前向差分求导数(感谢@EOL的编辑,但请注意NumPy的diff()不是一个求导函数):
def diff_fwd(x, y): 
    return np.diff(y)/np.diff(x)

“中心差分”(根据数据间距可能不一定是中心差分):
def diff_central(x, y):
    x0 = x[:-2]
    x1 = x[1:-1]
    x2 = x[2:]
    y0 = y[:-2]
    y1 = y[1:-1]
    y2 = y[2:]
    f = (x2 - x1)/(x2 - x0)
    return (1-f)*(y2 - y1)/(x2 - x1) + f*(y1 - y0)/(x1 - x0)

其中y包含函数评估,x对应于“时间”,这样您就可以使用任意区间。


前向差分和中心差分是什么? - user3123955
请查看@user3123955 这里有例子,以了解这些数值方法的概述。 - Saullo G. P. Castro
1
更直观易懂的方法 numpy.diff(y) 可以提供类似于 y[1:] - y[:-1] 的效果。 - Eric O. Lebigot
1
很好。实际上,diff()不代表“微分”,而是代表“差异”。顺便说一句,中心差异在NumPy中已经存在:numpy.gradient()(http://docs.scipy.org/doc/numpy/reference/generated/numpy.gradient.html#numpy.gradient)。:) - Eric O. Lebigot
这个公式怎么运作的?我以为中心差分只是 (y2 - y0) / (x2 - x0)?我有什么遗漏吗? - Pwnna
显示剩余3条评论

6

这有点晚了,但我发现 @dllahr 的答案非常有用并且可以很容易地通过 numpy 实现:

>>> import numpy as np
>>> y = [1, 2, 3, 4, 5]
>>> dy = np.gradient(y)
>>> x = [1, 2, 4, 8, 10]
>>> dx = np.gradient(x)
>>> dy/dx
array([1., 0.66666667, 0.33333333, 0.33333333, 0.5])

4

这可能没有提供是因为您可以通过对因变量(y值)和自变量(在您的特定情况下,时间戳)进行求导,然后将第一个向量除以第二个向量来代替。

求导数的定义是:

f' = dy / dx

或者在您的情况下:
f'(t) = dy / dt

您可以使用差分函数来计算每个数值dy,使用差分函数来计算您的数值dt,然后对这些数组进行元素除法运算,以确定每个点上的f'(t)。

2

1

自从最新的NumPy发布(1.13),numpy.gradient已经实现了这个特性(documentation):

>>> #only numpy 1.13 and above
>>> import numpy as np
>>> y = [1, 3, 4, 6, 11]
>>> x = [0, 1, 5, 10, 11]
>>> np.gradient(y, x)
array([ 2.        ,  1.65      ,  0.31666667,  4.23333333,  5.        ])

这里x中的值标记了y中y值的x坐标。

那么这与早期版本相比是非常不同的,对吧?例如,我正在使用1.11.3版本,其文档表明np.gradient(y, x)将此x视为delta x,而不是y的坐标。如果您没有注意版本,则这是一个非常危险的陷阱,结果将完全且无声地错误。 - Jason
@Jason 确实,我自己也曾经“中招”(https://dev59.com/LqTja4cB1Zd3GeqPCXov)。这只是一个问题,对于运行新版本代码的旧版本而言,因为新版本向后兼容(据我所知)。如果x是一个单独的数字,它会将其视为delta x。 - Neinstein
我刚刚在提交新问题时(这里 https://stackoverflow.com/q/46701906/2005415),在注意到你的回复前只有1秒钟。我不确定是否应该删除它还是保留它?但这是一个非常讨厌的错误,我不知道该怎么办,是编写自己的实现吗? - Jason
@Jason 我会放着不管,并在评论中提到我的问题作为“相关问题”。这样社区就可以自行决定它是否是重复的。(我不想自己评论,那看起来像是在刷声望...) - Neinstein
我不理解,结果是如何计算的,我无法得出 [2.0, 1.65, 0.31666667, 4.23333333, 5.0]。 - Pranshu Gupta

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