这本书实战是非常有借鉴作用的。尤其是这几个例子一步一步练下来还是非常有收获,但是我在运行原版程序的时候遇到一些问题,搜了一下全网,大家遇见的问题还是挺多的。可能是因为python编译器的版本迭代的问题。
运行环境:vscode 1.61.0 / Python 3.8.8 / Anaconda 2.03
我在本章遇见的几个问题:
1- Scipy的Lagrange()函数结果有问题
2- 数组的np.nan的处理使用reindex()的问题
针对以上问题
1- 参照知乎的一篇文章重写了lagrange插值函数五分钟理解拉格朗日插值法与python实现 - 知乎插值法是数值分析的基础知识之一,本文介绍的拉格朗日插值法是一种多项式插值法,可以用于数据不完整时的填补工作,本文包含理论介绍和python实现两个部分。 1、什么是插值问题?假设自己拥有下面的数值序列,由于…https://zhuanlan.zhihu.com/p/91631703
2- 直接用reindex()失败,重新调整程序传参
运行结果符合书中结论。
我做了非常详细的注释,直接上代码:
# %load 6-1_Lagrange_interpolation.py
# 拉格朗日插值代码
import pandas as pd # 导入数据分析库Pandas
# from scipy.interpolate import lagrange # 导入拉格朗日插值函数,原书这个函数不好用,我查回去看了半天没琢磨明白,只能自己构建 lagrange函数
import numpy as np
inputfile = '../data/missing_data.xls' # 输入数据路径,需要使用Excel格式;
outputfile = '../tmp/missing_data_processed.xls' # 输出数据路径,需要使用Excel格式
data = pd.read_excel(inputfile, header=None) # 读入数据
# 自定义列向量插值函数
# s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5): #s是data['销售'],n是插入位置,即data['销售'][j]的index:j
ns_1 = list(range(n-k, n))
ns_2 = list(range(n+1,n+1+k))
ns = ns_1 + ns_2
print('-------组----------')
print('作为Lagrange计算的数据index:', ns,' 个数:', len(ns))
# y = s.reindex([list(range(n - k, n)) + list(range(n + 1, n + 1 + k))]) # 取数, 原书代码这句一直导致y为空值,索引对上了,但是似乎reindex()函数运行有问题
y = s.reindex(ns) # 将 (-5,-1)和(1,5)单独计算再代入reindex()就可以了,蜜汁…… # reindex()函数将list中对应的np.nan替换成空值。
print('after reindex:',list(y))
y = y[y.notnull()] # 剔除空值
print('after kill np.nan:',list(y),' #number:', len(y))
# return lagrange(y.index, list(y))(n) # 插值并返回插值结果 SciPY的拉格朗日函数结果有问题
return lag_insert(y.index,list(y),n) #插入n,即x_i
def lag_insert(x,y,x_i): # (x,y)是原数据上的[],x_i是插入点的x值,求l(x)的基函数
l=np.zeros(shape=len(x),) #创建和x[]一样长的空数组,初始化基函数l(x)
for i in range(len(x)):
l[i]=1
for j in range(len(x)):
if i != j:
l[i]=l[i]*(x_i-x[j])/(x[i]-x[j])
else:
pass
L=0
for i in range(len(x)):
L += y[i]*l[i]
return L
# 逐个元素判断是否需要插值
for i in data.columns:
for j in range(len(data[i])):
if (data[i].isnull())[j]: # 如果为空即插值。
# print(data[i][j]), i,j, data[i].isnull()
data[i][j] = ployinterp_column(data[i], j)
print('第i列:',i,' 第j行:',j,' value:',data[i][j])
data.to_excel(outputfile, header=None, index=False) # 输出结果
print('END')
原始数组数据从Github上即可找到,在每次循环我都print了运行的阶段结果,方便有兴趣的读者了解过程。



