我有一个函数,它是一个相对较大的数据集的插值。我使用线性插值interp1d
,因此有许多非平滑尖点,如this。 scipy的quad
函数会因尖锐点而发出警告。我想知道如何在没有警告的情况下进行整合?
谢谢!
感谢所有答案。在这里,我总结了解决方案,以防其他一些人遇到同样的问题:
points
来避免警告并获得更准确的结果。 limit=50
的默认限制(quad
),因此我选择quad(f_interp, a, b, limit=2*p.shape[0], points=p)
来避免所有这些警告。a
和b
与数据集x
的起点或终点不同,则可以p
选择点p = x[where(x>=a and x<=b)]
答案 0 :(得分:2)
quad
接受一个名为points
的可选参数。根据文件:
点:(浮点数序列,整数),可选
有界积分区间中的一系列断点 可能发生局部困难(例如,奇点, 不连续性)。序列不必排序。
在您的情况下,“困难”points
正好是数据点的x坐标。这是一个例子:
import numpy as np
from scipy.integrate import quad
np.random.seed(123)
# generate random data set
x = np.arange(0,10)
y = np.random.rand(10)
# construct a linear interpolation function of the data set
f_interp = lambda xx: np.interp(xx, x, y)
现在将quad
称为
quad(f_interp,0,9)
返回一系列警告以及
(4.89770017785734, 1.3762838395159349e-05)
如果您提供points
参数,即
quad(f_interp,0,9, points = x)
它没有发出警告,结果是
(4.8977001778573435, 5.437539505167948e-14)
与前一次调用相比,这也意味着结果的准确性要高得多。
答案 1 :(得分:2)
而不是interp1d
,您可以使用scipy.interpolate.InterpolatedUnivariateSpline
。该插补器具有计算定积分的方法integral(a, b)
。
以下是一个例子:
import numpy as np
from scipy.interpolate import InterpolatedUnivariateSpline
import matplotlib.pyplot as plt
# Create some test data.
x = np.linspace(0, np.pi, 21)
np.random.seed(12345)
y = np.sin(1.5*x) + np.random.laplace(scale=0.35, size=len(x))**3
# Create the interpolator. Use k=1 for linear interpolation.
finterp = InterpolatedUnivariateSpline(x, y, k=1)
# Create a finer mesh of points on which to compute the integral.
xx = np.linspace(x[0], x[-1], 5*len(x))
# Use the interpolator to compute the integral from 0 to t for each
# t in xx.
qq = [finterp.integral(0, t) for t in xx]
# Plot stuff
p = plt.plot(x, y, '.', label='data')
plt.plot(x, y, '-', color=p[0].get_color(), label='linear interpolation')
plt.plot(xx, qq, label='integral of linear interpolation')
plt.grid()
plt.legend(framealpha=1, shadow=True)
plt.show()
情节: