univariate_tools.interpolation
Interpolation holds classes and functions important for interpolating data
1#----------------------------------------------------------------------------- 2# Name: Interpolation 3# Purpose: To hold functions and classes for interpolating data 4# Author: Aric Sanders 5# Created: 04/03/2025 6# License: MIT License 7#----------------------------------------------------------------------------- 8""" Interpolation holds classes and functions important for interpolating data 9 10 """ 11 12#----------------------------------------------------------------------------- 13# Standard Imports 14import os 15import sys 16import re 17#----------------------------------------------------------------------------- 18# Third Party Imports 19sys.path.append(os.path.join(os.path.dirname( __file__ ), '..')) 20import matplotlib.pyplot as plt 21import numpy as np 22from scipy import interpolate 23from sklearn.gaussian_process import GaussianProcessRegressor 24from sklearn.gaussian_process.kernels import RBF 25from scipy.interpolate import make_smoothing_spline 26import statsmodels.api as sm 27from scipy import signal 28from skmisc.loess import loess 29import scipy 30#----------------------------------------------------------------------------- 31# Module Constants 32 33#----------------------------------------------------------------------------- 34# Module Functions 35 36 37def reverse_regressor(x_data,y_data,new_y_data,method="lowess",**options): 38 """reverse_regressor returns a series of new_x_data points given observed x_data, y_data and the desired 39 new_y_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation 40 possibilities. 41 42 Current methods are lowess,loess, 1d, gpr and spline. 43 ********************************************************************************************* 44 refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are 45 ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, 46 ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’ 47 **************************************************************************************** 48 https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html 49 *********************************************************************************************** 50 https://has2k1.github.io/scikit-misc/stable/index.html 51 ****************************************************** 52 https://scikit-learn.org/stable/modules/gaussian_process.html 53 *************************************************************** 54 https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html 55 ********************************************************************************""" 56 defaults = {} 57 interpolation_options = {} 58 for key,value in defaults.items(): 59 interpolation_options[key] = value 60 for key, value in options.items(): 61 interpolation_options[key] = value 62 new_x_data = None 63 64 if re.search("lowess",method,re.IGNORECASE): 65 lowess_key_words = ['frac'] 66 lowess_options = {'frac':.2} 67 for key,value in interpolation_options.items(): 68 if key in lowess_key_words: 69 lowess_options[key]=value 70 interpolation_result= sm.nonparametric.lowess(endog=x_data, 71 exog=y_data, 72 xvals = new_y_data, 73 **lowess_options) 74 new_x_data = interpolation_result 75 76 if re.search("loess",method,re.IGNORECASE): 77 loess_key_words = ['p','span','family','degree','normalize'] 78 loess_options = {"span":0.65, "p":1, "family":'gaussian', "degree":1, "normalize":False} 79 for key,value in interpolation_options.items(): 80 if key in loess_key_words: 81 loess_options[key]=value 82 lo = loess(y_data, x_data, **loess_options) 83 lo.fit() 84 pred = lo.predict(new_y_data, stderror=True) 85 new_x_data = np.array(pred.values) 86 87 if re.search("1d",method,re.IGNORECASE): 88 interp1d_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 89 interp1d_options ={"fill_value":"extrapolate"} 90 for key,value in interpolation_options.items(): 91 if key in interp1d_key_words: 92 interp1d_options[key]=value 93 interpolation_function = scipy.interpolate.interp1d(y_data, 94 x_data,**interp1d_options) 95 new_x_data = interpolation_function(new_y_data) 96 97 elif re.search("gpr",method,re.IGNORECASE): 98 gpr_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 99 gpr_options ={"kernel":1 * RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e2)), 100 "n_restarts_optimizer":9} 101 for key,value in interpolation_options.items(): 102 if key in gpr_key_words: 103 gpr_options[key]=value 104 105 gaussian_process = GaussianProcessRegressor(**gpr_options) 106 gaussian_process.fit(y_data.reshape(-1,1), x_data) 107 mean_prediction, std_prediction = gaussian_process.predict(new_y_data.reshape(-1,1), return_std=True) 108 new_x_data = mean_prediction 109 110 elif re.search("spline",method,re.IGNORECASE): 111 coordinates = zip(y_data,x_data) 112 ordered_array = np.array(sorted(coordinates)) 113 interpolation_function = scipy.interpolate.make_smoothing_spline(ordered_array.T[0],ordered_array.T[1]) 114 new_x_data = interpolation_function(new_y_data) 115 116 return new_x_data 117 118def interpolate_data(x_data,y_data,new_x_data,method="lowess",**options): 119 """interpolate_data returns a series of new_y_data points given observed x_data, y_data and the desired 120 new_x_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation 121 possibilites. Current methods are lowess,loess, 1d, gpr and spline. 122 ********************************************************************************************* 123 refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are 124 ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, 125 ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’ 126 **************************************************************************************** 127 https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html 128 *********************************************************************************************** 129 https://scikit-learn.org/stable/modules/gaussian_process.html 130 *************************************************************** 131 https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html 132 ********************************************************************************""" 133 defaults = {} 134 interpolation_options = {} 135 for key,value in defaults.items(): 136 interpolation_options[key] = value 137 for key, value in options.items(): 138 interpolation_options[key] = value 139 new_y_data = None 140 141 if re.search("lowess",method,re.IGNORECASE): 142 lowess_key_words = ['frac'] 143 lowess_options = {} 144 for key,value in interpolation_options.items(): 145 if key in lowess_key_words: 146 lowess_options[key]=value 147 interpolation_result= sm.nonparametric.lowess(y_data, 148 x_data, 149 xvals = new_x_data, 150 **lowess_options) 151 new_y_data = interpolation_result 152 153 154 if re.search("loess",method,re.IGNORECASE): 155 loess_key_words = ['p','span','family','degree','normalize'] 156 loess_options = {"span":0.65, "p":1, "family":'gaussian', "degree":1, "normalize":False} 157 for key,value in interpolation_options.items(): 158 if key in loess_key_words: 159 loess_options[key]=value 160 lo = loess(x_data, y_data, **loess_options) 161 lo.fit() 162 pred = lo.predict(new_x_data, stderror=True) 163 new_y_data = np.array(pred.values) 164 165 if re.search("1d",method,re.IGNORECASE): 166 interp1d_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 167 interp1d_options ={"fill_value":"extrapolate"} 168 for key,value in interpolation_options.items(): 169 if key in interp1d_key_words: 170 interp1d_options[key]=value 171 interpolation_function = scipy.interpolate.interp1d(x_data, 172 y_data,**interp1d_options) 173 new_y_data = interpolation_function(new_x_data) 174 175 elif re.search("gpr",method,re.IGNORECASE): 176 gpr_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 177 gpr_options ={"kernel":1 * RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e2)), 178 "n_restarts_optimizer":9} 179 for key,value in interpolation_options.items(): 180 if key in gpr_key_words: 181 gpr_options[key]=value 182 gaussian_process = GaussianProcessRegressor(**gpr_options) 183 gaussian_process.fit(x_data.reshape(-1,1), y_data) 184 mean_prediction, std_prediction = gaussian_process.predict(new_x_data.reshape(-1,1), return_std=True) 185 new_y_data = mean_prediction 186 187 elif re.search("spline",method,re.IGNORECASE): 188 coordinates = zip(x_data,y_data) 189 ordered_array = np.array(sorted(coordinates)) 190 interpolation_function = scipy.interpolate.make_smoothing_spline(ordered_array.T[0],ordered_array.T[1]) 191 new_y_data = interpolation_function(new_x_data) 192 193 return new_y_data 194 195 196 197 198 199#----------------------------------------------------------------------------- 200# Module Classes 201 202#----------------------------------------------------------------------------- 203# Module Scripts 204def test_interpolate_data(): 205 x_data = np.linspace(-6,6,500) 206 signal = np.sin(x_data)+np.random.normal(scale=.5,size=len(x_data)) 207 plt.plot(x_data,signal,".",label="Original Data") 208 for interp_type in ["lowess","loess", "1d", "gpr","spline"]: 209 new_x = np.linspace(-2,2,500) 210 interp_data = interpolate_data(x_data=x_data,y_data=signal,new_x_data=new_x,method=interp_type) 211 plt.plot(new_x,interp_data,label=interp_type) 212 plt.legend() 213 plt.show() 214 215def test_reverse_regressor(): 216 x_data = np.linspace(-6,6,200) 217 signal = 2*x_data+1+np.random.normal(scale=.2,size=len(x_data)) 218 plt.plot(x_data,signal,".",label="Original Data",alpha=.3) 219 220 for interp_type in ["lowess","loess", "1d", "gpr","spline"]: 221 try: 222 new_y = np.linspace(-2,5,10) 223 new_x = reverse_regressor(x_data=x_data,y_data=signal,new_y_data=new_y,method=interp_type) 224 print(f"{interp_type}:{new_x},{new_y}") 225 plt.plot(new_x,new_y,label=interp_type,linewidth=2,linestyle="dashed") 226 except Exception as e: 227 print(e) 228 plt.legend() 229 plt.show() 230 231def test_lowess(): 232 x_data = np.linspace(-6,6,100) 233 y_data = 2*x_data+1+np.random.normal(scale=.1,size=len(x_data)) 234 new_y_data = np.linspace(-2,5,10) 235 interpolation_result= sm.nonparametric.lowess(endog=x_data, 236 exog=y_data, 237 xvals = new_y_data, 238 frac=.2) 239 #print(interpolation_result) 240 new_x = reverse_regressor(x_data=x_data,y_data=y_data,new_y_data=new_y_data,method="lowess") 241 plt.plot(x_data,y_data,label="original data") 242 plt.plot(interpolation_result,new_y_data,label="lowess fit") 243 plt.plot(new_x,new_y_data,label="lowess fit 2") 244 plt.show() 245 246#----------------------------------------------------------------------------- 247# Module Runner 248if __name__ == '__main__': 249 #test_interpolate_data() 250 test_reverse_regressor() 251 #test_lowess()
38def reverse_regressor(x_data,y_data,new_y_data,method="lowess",**options): 39 """reverse_regressor returns a series of new_x_data points given observed x_data, y_data and the desired 40 new_y_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation 41 possibilities. 42 43 Current methods are lowess,loess, 1d, gpr and spline. 44 ********************************************************************************************* 45 refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are 46 ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, 47 ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’ 48 **************************************************************************************** 49 https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html 50 *********************************************************************************************** 51 https://has2k1.github.io/scikit-misc/stable/index.html 52 ****************************************************** 53 https://scikit-learn.org/stable/modules/gaussian_process.html 54 *************************************************************** 55 https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html 56 ********************************************************************************""" 57 defaults = {} 58 interpolation_options = {} 59 for key,value in defaults.items(): 60 interpolation_options[key] = value 61 for key, value in options.items(): 62 interpolation_options[key] = value 63 new_x_data = None 64 65 if re.search("lowess",method,re.IGNORECASE): 66 lowess_key_words = ['frac'] 67 lowess_options = {'frac':.2} 68 for key,value in interpolation_options.items(): 69 if key in lowess_key_words: 70 lowess_options[key]=value 71 interpolation_result= sm.nonparametric.lowess(endog=x_data, 72 exog=y_data, 73 xvals = new_y_data, 74 **lowess_options) 75 new_x_data = interpolation_result 76 77 if re.search("loess",method,re.IGNORECASE): 78 loess_key_words = ['p','span','family','degree','normalize'] 79 loess_options = {"span":0.65, "p":1, "family":'gaussian', "degree":1, "normalize":False} 80 for key,value in interpolation_options.items(): 81 if key in loess_key_words: 82 loess_options[key]=value 83 lo = loess(y_data, x_data, **loess_options) 84 lo.fit() 85 pred = lo.predict(new_y_data, stderror=True) 86 new_x_data = np.array(pred.values) 87 88 if re.search("1d",method,re.IGNORECASE): 89 interp1d_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 90 interp1d_options ={"fill_value":"extrapolate"} 91 for key,value in interpolation_options.items(): 92 if key in interp1d_key_words: 93 interp1d_options[key]=value 94 interpolation_function = scipy.interpolate.interp1d(y_data, 95 x_data,**interp1d_options) 96 new_x_data = interpolation_function(new_y_data) 97 98 elif re.search("gpr",method,re.IGNORECASE): 99 gpr_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 100 gpr_options ={"kernel":1 * RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e2)), 101 "n_restarts_optimizer":9} 102 for key,value in interpolation_options.items(): 103 if key in gpr_key_words: 104 gpr_options[key]=value 105 106 gaussian_process = GaussianProcessRegressor(**gpr_options) 107 gaussian_process.fit(y_data.reshape(-1,1), x_data) 108 mean_prediction, std_prediction = gaussian_process.predict(new_y_data.reshape(-1,1), return_std=True) 109 new_x_data = mean_prediction 110 111 elif re.search("spline",method,re.IGNORECASE): 112 coordinates = zip(y_data,x_data) 113 ordered_array = np.array(sorted(coordinates)) 114 interpolation_function = scipy.interpolate.make_smoothing_spline(ordered_array.T[0],ordered_array.T[1]) 115 new_x_data = interpolation_function(new_y_data) 116 117 return new_x_data
reverse_regressor returns a series of new_x_data points given observed x_data, y_data and the desired new_y_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation possibilities.
Current methods are lowess,loess, 1d, gpr and spline.
refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’
https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html
https://has2k1.github.io/scikit-misc/stable/index.html
https://scikit-learn.org/stable/modules/gaussian_process.html
https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html
119def interpolate_data(x_data,y_data,new_x_data,method="lowess",**options): 120 """interpolate_data returns a series of new_y_data points given observed x_data, y_data and the desired 121 new_x_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation 122 possibilites. Current methods are lowess,loess, 1d, gpr and spline. 123 ********************************************************************************************* 124 refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are 125 ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, 126 ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’ 127 **************************************************************************************** 128 https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html 129 *********************************************************************************************** 130 https://scikit-learn.org/stable/modules/gaussian_process.html 131 *************************************************************** 132 https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html 133 ********************************************************************************""" 134 defaults = {} 135 interpolation_options = {} 136 for key,value in defaults.items(): 137 interpolation_options[key] = value 138 for key, value in options.items(): 139 interpolation_options[key] = value 140 new_y_data = None 141 142 if re.search("lowess",method,re.IGNORECASE): 143 lowess_key_words = ['frac'] 144 lowess_options = {} 145 for key,value in interpolation_options.items(): 146 if key in lowess_key_words: 147 lowess_options[key]=value 148 interpolation_result= sm.nonparametric.lowess(y_data, 149 x_data, 150 xvals = new_x_data, 151 **lowess_options) 152 new_y_data = interpolation_result 153 154 155 if re.search("loess",method,re.IGNORECASE): 156 loess_key_words = ['p','span','family','degree','normalize'] 157 loess_options = {"span":0.65, "p":1, "family":'gaussian', "degree":1, "normalize":False} 158 for key,value in interpolation_options.items(): 159 if key in loess_key_words: 160 loess_options[key]=value 161 lo = loess(x_data, y_data, **loess_options) 162 lo.fit() 163 pred = lo.predict(new_x_data, stderror=True) 164 new_y_data = np.array(pred.values) 165 166 if re.search("1d",method,re.IGNORECASE): 167 interp1d_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 168 interp1d_options ={"fill_value":"extrapolate"} 169 for key,value in interpolation_options.items(): 170 if key in interp1d_key_words: 171 interp1d_options[key]=value 172 interpolation_function = scipy.interpolate.interp1d(x_data, 173 y_data,**interp1d_options) 174 new_y_data = interpolation_function(new_x_data) 175 176 elif re.search("gpr",method,re.IGNORECASE): 177 gpr_key_words = ["kind","axis","copy","bounds_error","fill_value","assume_sorted"] 178 gpr_options ={"kernel":1 * RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e2)), 179 "n_restarts_optimizer":9} 180 for key,value in interpolation_options.items(): 181 if key in gpr_key_words: 182 gpr_options[key]=value 183 gaussian_process = GaussianProcessRegressor(**gpr_options) 184 gaussian_process.fit(x_data.reshape(-1,1), y_data) 185 mean_prediction, std_prediction = gaussian_process.predict(new_x_data.reshape(-1,1), return_std=True) 186 new_y_data = mean_prediction 187 188 elif re.search("spline",method,re.IGNORECASE): 189 coordinates = zip(x_data,y_data) 190 ordered_array = np.array(sorted(coordinates)) 191 interpolation_function = scipy.interpolate.make_smoothing_spline(ordered_array.T[0],ordered_array.T[1]) 192 new_y_data = interpolation_function(new_x_data) 193 194 return new_y_data
interpolate_data returns a series of new_y_data points given observed x_data, y_data and the desired new_x_data. This function is intended as a wrapper to create a clean interface to the large number of interpolation possibilites. Current methods are lowess,loess, 1d, gpr and spline.
refs: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html, options for kind are ‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’. ‘zero’, ‘slinear’, ‘quadratic’ and ‘cubic’
https://www.statsmodels.org/dev/generated/statsmodels.nonparametric.smoothers_lowess.lowess.html
https://scikit-learn.org/stable/modules/gaussian_process.html
https://docs.scipy.org/doc/scipy/tutorial/interpolate/smoothing_splines.html
205def test_interpolate_data(): 206 x_data = np.linspace(-6,6,500) 207 signal = np.sin(x_data)+np.random.normal(scale=.5,size=len(x_data)) 208 plt.plot(x_data,signal,".",label="Original Data") 209 for interp_type in ["lowess","loess", "1d", "gpr","spline"]: 210 new_x = np.linspace(-2,2,500) 211 interp_data = interpolate_data(x_data=x_data,y_data=signal,new_x_data=new_x,method=interp_type) 212 plt.plot(new_x,interp_data,label=interp_type) 213 plt.legend() 214 plt.show()
216def test_reverse_regressor(): 217 x_data = np.linspace(-6,6,200) 218 signal = 2*x_data+1+np.random.normal(scale=.2,size=len(x_data)) 219 plt.plot(x_data,signal,".",label="Original Data",alpha=.3) 220 221 for interp_type in ["lowess","loess", "1d", "gpr","spline"]: 222 try: 223 new_y = np.linspace(-2,5,10) 224 new_x = reverse_regressor(x_data=x_data,y_data=signal,new_y_data=new_y,method=interp_type) 225 print(f"{interp_type}:{new_x},{new_y}") 226 plt.plot(new_x,new_y,label=interp_type,linewidth=2,linestyle="dashed") 227 except Exception as e: 228 print(e) 229 plt.legend() 230 plt.show()
232def test_lowess(): 233 x_data = np.linspace(-6,6,100) 234 y_data = 2*x_data+1+np.random.normal(scale=.1,size=len(x_data)) 235 new_y_data = np.linspace(-2,5,10) 236 interpolation_result= sm.nonparametric.lowess(endog=x_data, 237 exog=y_data, 238 xvals = new_y_data, 239 frac=.2) 240 #print(interpolation_result) 241 new_x = reverse_regressor(x_data=x_data,y_data=y_data,new_y_data=new_y_data,method="lowess") 242 plt.plot(x_data,y_data,label="original data") 243 plt.plot(interpolation_result,new_y_data,label="lowess fit") 244 plt.plot(new_x,new_y_data,label="lowess fit 2") 245 plt.show()