# Python 如何设置SciPy插值器以最准确地保存数据

def reduce_dataset(x_list, y_list, num_interpolation_points):
points = np.array([x_list, y_list]).T
distance = np.cumsum( np.sqrt(np.sum( np.diff(points, axis=0)**2, axis=1 )) )
distance = np.insert(distance, 0, 0)/distance[-1]
interpolator =  interp1d(distance, points, kind='quadratic', axis=0)
results = interpolator(np.linspace(0, 1, num_interpolation_points)).T.tolist()
new_xs = results[0]
new_ys = results[1]
return new_xs, new_ys

xs, ys = reduce_dataset(xs,ys, 50)
colors = cm.rainbow(np.linspace(0, 1, len(ys)))
i = 0
for y, c in zip(ys, colors):
plt.scatter(xs[i], y, color=c)
i += 1


## 推荐答案

interp1d将返回根据您提供的xy坐标构建的插补器对象.它们根本不需要均匀分布.

import numpy as np
from scipy.interpolate import interp1d

import matplotlib.pyplot as plt

# Generate fake data
x = np.linspace(1, 3, 1000)
y = (x - 2)**3

# interpolation
interpolator = interp1d(x, y)

# different xnews
N = 20
xnew_linspace = np.linspace(x.min(), x.max(), N)  # linearly spaced
xnew_logspace = np.logspace(np.log10(x.min()), np.log10(x.max()), N)  # log spaced

# spacing based on curvature
idx = np.round(np.linspace(0, len(curvature) - 1, N)).astype(int)
epsilon = 1e-1

a = (0.99 * x.max() - x.min()) / np.sum(1 / (curvature[idx] + epsilon))
xnew_curvature = np.insert(x.min() + np.cumsum(a / (curvature[idx] + epsilon)), 0, x.min())

fig, axarr = plt.subplots(2, 2, layout='constrained', sharex=True, sharey=True)

axarr[0, 0].plot(x, y)
for ax, xnew in zip(axarr.flatten()[1:], [xnew_linspace, xnew_logspace, xnew_curvature]):
ax.plot(xnew, interpolator(xnew), '.--')

axarr[0, 0].set_title('base signal')
axarr[0, 1].set_title('linearly spaced')
axarr[1, 0].set_title('log spaced')
axarr[1, 1].set_title('curvature based spaced')

plt.savefig('test_interp1d.png', dpi=400)