本文目录导读:

我来详细介绍如何使用Scipy进行插值计算,包括几种常用的插值方法。
基础准备
import numpy as np from scipy import interpolate import matplotlib.pyplot as plt # 设置中文显示 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False
一维插值方法
1 线性插值 (interp1d)
# 创建样本数据
x = np.linspace(0, 10, 11) # 11个点
y = np.sin(x)
# 创建插值函数
f_linear = interpolate.interp1d(x, y, kind='linear')
f_cubic = interpolate.interp1d(x, y, kind='cubic')
f_quadratic = interpolate.interp1d(x, y, kind='quadratic')
# 生成插值点
x_new = np.linspace(0, 10, 101)
# 计算插值
y_linear = f_linear(x_new)
y_cubic = f_cubic(x_new)
y_quadratic = f_quadratic(x_new)
# 可视化
plt.figure(figsize=(12, 8))
plt.plot(x, y, 'o', label='原始数据点', markersize=8)
plt.plot(x_new, y_linear, '-', label='线性插值')
plt.plot(x_new, y_cubic, '--', label='三次样条插值')
plt.plot(x_new, y_quadratic, ':', label='二次插值')
plt.plot(x_new, np.sin(x_new), 'k-', label='真实函数', alpha=0.5)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')'不同插值方法比较')
plt.grid(True)
plt.show()
2 样条插值
# 使用样条插值 x = np.linspace(0, 10, 10) y = np.sin(x) # 创建样条插值对象 spline = interpolate.UnivariateSpline(x, y) spline_smooth = interpolate.UnivariateSpline(x, y, s=0.5) # 带平滑参数 # 生成插值点 x_new = np.linspace(0, 10, 100) y_spline = spline(x_new) y_spline_smooth = spline_smooth(x_new) plt.figure(figsize=(10, 6)) plt.plot(x, y, 'o', label='原始数据', markersize=8) plt.plot(x_new, y_spline, '-', label='样条插值') plt.plot(x_new, y_spline_smooth, '--', label='平滑样条(s=0.5)') plt.plot(x_new, np.sin(x_new), 'k:', label='真实函数') plt.legend()'样条插值示例') plt.grid(True) plt.show()
多维插值
1 二维插值 (griddata)
from scipy.interpolate import griddata
# 创建二维散点数据
np.random.seed(42)
points = np.random.rand(100, 2) * 10 # 100个随机点
values = np.sin(points[:, 0]) * np.cos(points[:, 1]) # 函数值
# 创建网格
xi = np.linspace(0, 10, 50)
yi = np.linspace(0, 10, 50)
xi, yi = np.meshgrid(xi, yi)
# 不同插值方法
methods = ['linear', 'cubic', 'nearest']
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
# 原始数据点
axes[0].scatter(points[:, 0], points[:, 1], c=values, cmap='viridis', s=50)
axes[0].set_title('原始散点数据')
# 各种插值方法
for i, method in enumerate(methods, 1):
zi = griddata(points, values, (xi, yi), method=method)
im = axes[i].imshow(zi, extent=[0, 10, 0, 10], origin='lower',
cmap='viridis', aspect='auto')
axes[i].set_title(f'{method}插值')
plt.colorbar(im, ax=axes[i])
plt.tight_layout()
plt.show()
2 二维样条插值 (RectBivariateSpline)
# 创建规则的二维网格数据
x = np.linspace(0, 10, 20)
y = np.linspace(0, 10, 20)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
# 创建二维样条插值
spline_2d = interpolate.RectBivariateSpline(x, y, Z)
# 生成精细网格
x_new = np.linspace(0, 10, 100)
y_new = np.linspace(0, 10, 100)
Z_new = spline_2d(x_new, y_new)
# 可视化
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
im1 = ax1.imshow(Z, extent=[0, 10, 0, 10], origin='lower', cmap='coolwarm', aspect='auto')
ax1.set_title('原始数据(20x20)')
plt.colorbar(im1, ax=ax1)
im2 = ax2.imshow(Z_new, extent=[0, 10, 0, 10], origin='lower', cmap='coolwarm', aspect='auto')
ax2.set_title('插值后(100x100)')
plt.colorbar(im2, ax=ax2)
plt.tight_layout()
plt.show()
实际应用案例
1 温度数据插值
# 模拟气象站温度数据
hours = np.array([0, 3, 6, 9, 12, 15, 18, 21]) # 测量时间
temperatures = np.array([15, 12, 10, 18, 25, 28, 22, 17]) # 温度(°C)
# 创建连续时间点
hours_dense = np.linspace(0, 24, 241) # 每10分钟一个点
# 不同插值方法比较
methods = {
'线性': 'linear',
'二次': 'quadratic',
'三次': 'cubic'
}
plt.figure(figsize=(12, 6))
for label, method in methods.items():
f = interpolate.interp1d(hours, temperatures, kind=method)
temp_dense = f(hours_dense)
plt.plot(hours_dense, temp_dense, label=label, linewidth=2)
plt.plot(hours, temperatures, 'ro', label='观测数据', markersize=10)
plt.xlabel('时间 (小时)')
plt.ylabel('温度 (°C)')'气温变化插值')
plt.legend()
plt.grid(True)
plt.xticks(range(0, 25, 3))
plt.show()
2 缺失数据填充
# 模拟带有缺失值的时间序列
time = np.arange(0, 10, 0.5)
data = np.sin(time)
data[5:8] = np.nan # 人为制造缺失值
# 分离有效数据和缺失位置
valid_idx = ~np.isnan(data)
time_valid = time[valid_idx]
data_valid = data[valid_idx]
# 对缺失值进行插值
f = interpolate.interp1d(time_valid, data_valid, kind='cubic')
time_missing = time[~valid_idx]
data_filled = f(time_missing)
# 可视化
plt.figure(figsize=(12, 5))
plt.plot(time, np.sin(time), 'g-', label='真实值', alpha=0.5)
plt.plot(time[valid_idx], data_valid, 'bo', label='有效数据', markersize=8)
plt.plot(time_missing, data_filled, 'r^', label='插值填充', markersize=8)
plt.xlabel('时间')
plt.ylabel('数值')'缺失数据插值填充')
plt.legend()
plt.grid(True)
plt.show()
高级插值方法
1 径向基函数插值 (RBF)
from scipy.interpolate import RBFInterpolator
# 创建不规则散点数据
np.random.seed(42)
x = np.random.rand(50) * 10
y = np.random.rand(50) * 10
values = np.sin(x) * np.cos(y) + np.random.randn(50) * 0.1
# 创建RBF插值
rbf = RBFInterpolator(np.column_stack([x, y]), values, kernel='multiquadric')
# 创建网格进行评估
x_grid, y_grid = np.meshgrid(np.linspace(0, 10, 100), np.linspace(0, 10, 100))
z_grid = rbf(np.column_stack([x_grid.ravel(), y_grid.ravel()]))
z_grid = z_grid.reshape(x_grid.shape)
# 可视化
plt.figure(figsize=(10, 8))
plt.contourf(x_grid, y_grid, z_grid, levels=20, cmap='viridis')
plt.colorbar(label='插值值')
plt.scatter(x, y, c=values, s=100, edgecolor='white', linewidth=1, cmap='viridis')
plt.xlabel('X')
plt.ylabel('Y')'径向基函数插值')
plt.show()
性能比较
import time
# 生成测试数据
n_points = [10, 50, 100, 500, 1000]
methods = {'linear': 'linear', 'cubic': 'cubic', 'quadratic': 'quadratic'}
performance = {method: [] for method in methods}
for n in n_points:
x = np.linspace(0, 10, n)
y = np.sin(x)
x_new = np.linspace(0, 10, 1000)
for name, kind in methods.items():
start = time.time()
f = interpolate.interp1d(x, y, kind=kind)
y_new = f(x_new)
end = time.time()
performance[name].append(end - start)
# 绘制性能比较图
plt.figure(figsize=(10, 6))
for method, times in performance.items():
plt.plot(n_points, times, 'o-', label=method, linewidth=2)
plt.xlabel('数据点数量')
plt.ylabel('计算时间 (秒)')'插值方法性能比较')
plt.legend()
plt.grid(True)
plt.xscale('log')
plt.yscale('log')
plt.show()
Scipy提供了丰富的插值工具:
- 一维插值:使用
interp1d,支持多种插值方法 - 样条插值:
UnivariateSpline提供更灵活的平滑控制 - 多维插值:
griddata处理不规则数据,RectBivariateSpline处理规则网格 - 高级方法:RBF插值适合不规则散点数据
选择插值方法时需要考虑:
- 数据特点(规则/不规则)
- 精度要求
- 计算效率
- 是否需要平滑
这样就能应对大多数插值应用场景了!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播