Я пытаюсь создать одномерную сплайн-интерполяцию в python, чтобы соответствовать большому набору данных, и когда я рисую два, кажется, что есть большие различия. Я пытался установить коэффициент сглаживания на множество разных значений (включая ноль, поэтому он должен проходить через каждую точку данных), но когда я рисую два, я получаю большие различия.
##
# Univariate Spline Interpolation
##
## This function interpolates the data by creating multiple times the amount of points in the data set and fitting a spline to it
## Input:
# dataX - X axis that you corresponds to dataset
# dataY - Y axis of data to fit spline on (must be same size as dataX)
# multiple - the multiplication factor, default is 2 ( <1 - Less points, 1 - same amount of points, >1 - more points)
# order - order of spline, default is 4 (3 - Cubic, 4 - Quartic)
## Output
# splinedDataX - splined X Axis
# splinedDataY - splined Y Axis
def univariate_spline_interpolation( dataX, dataY, multiple=2, order=4):
#Libraries
from numpy import linspace,exp
from numpy.random import randn
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline, LSQUnivariateSpline
#Find sizes of x and y axis for comparison and multiple
sizeX = len(dataX)
sizeY = len(dataY)
#Error catching
if(sizeX != sizeY):
print "Data X axis and Y axis must have same size"
return
if(multiple <= 0):
print "Order must be greater than 0"
return
if(order < 1 or order >5):
print "Order must be 1 <= order <= 5"
return
#Create Spline
s = UnivariateSpline(dataX, dataY, k=3, s=0)
# s is smoothing factor so spline doesn't shoot off in between data points
#Positive smoothing factor used to choose the number of knots.
#Number of knots will be increased until the smoothing condition is satisfied:
# sum((w[i]*(y[i]-s(x[i])))**2,axis=0) <= s
#If None (default), s=len(w) which should be a good value if 1/w[i] is an estimate of the standard deviation of y[i].
#If 0, spline will interpolate through all data points.
#Create new axis based on numPoints
numPoints = sizeX * multiple #Find mumber of points for spline
startPt = dataX[1] #find value of first point on x axis
endPt = dataX[-1] #find value of last point on x axis
splinedDataX = linspace(startPt, endPt, numPoints) #create evenly spaced points on axis based on start, end, and number of desired data points
#Create Y axis of splined Data
splinedDataY = s(splinedDataX) #Create new Y axis with numPoints etnries of data splined to fit the original data
return splinedDataX, splinedDataY
##
# Text Cubic Spline
##
splinedX, splinedY = univariate_spline_interpolation(sensorTimestamp, filteredData[1], multiple=1)
print "old x data"
print "length", len(sensorTimestamp)
print "Starts", sensorTimestamp[0]
print "Ends", sensorTimestamp[-1]
print ""
print "new x data"
print "length", len(splinedX)
print "multiple", len(splinedX)/len(filteredData[1])
print "Starts", splinedX[0]
print "Ends", splinedX[-1]
print ""
print "old y data"
print "length", len(filteredData[1])
print "Starts", filteredData[1][0]
print "Ends", filteredData[1][-1]
print ""
print "new y data"
print "length", len(splinedY)
print "Starts", splinedY[0]
print "Ends", splinedY[-1]
difference = []
for i in splinedY:
difference.append(splinedY[i] - filteredData[1][i])
plt.figure(figsize=(20,3))
plt.plot(sensorTimestamp, filteredData[1], label='Non-Splined', marker='*')
plt.plot(splinedX, splinedY, label='Splined')
plt.plot(sensorTimestamp, difference, label='Difference', ls='--')
plt.title(' BW Filtered Data from LED 1')
plt.axis([19, 30, -300, 300])
plt.legend(loc='best')
plt.show()
Выходная печать:
old x data
length 14690
Starts 0.0
Ends 497.178565979
new x data
length 14690
multiple 1.0
Starts 0.0555429458618
Ends 497.178565979
old y data
length 14690
Starts 50.2707843894
Ends 341.661410048
new y data
length 14690
Starts 416.803282313
Ends 341.661410048
Как вы можете видеть, различия огромны, но на графике данные кажутся точно такими же точками (или очень близкими).