我们采集到的数据都是以离散的点的形式存在的,只有在采样点上才有具体的值,在其他区域都没有值数据。此时就需要插值分析,将采样点的数值根据一定的算法,推算出其他未采样区域的数值。
在讲scipy.interpolate类方法插值函数之前我们先讲两种常见的插值方法:待定系数法和拉格朗日法插值。
待定系数法插值:待定系数法插值在我们拥有n个插值节点时构造一个n次多项式,

然后可以构造非齐次线性方程组,

在高数或线性代数里,我们学过范德蒙德行列式,我们可以根据上述非齐次线性方程组构造出它的系数矩阵,

再根据解线性方程组的克拉默(克莱姆) 法则,线性方程组的解确定且唯一,由此我们便可以得到我们的插值函数。
由python代码编写如下:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
x0=np.linspace(-10,10,21)
y0=np.sin(x0)
plt.plot(x0,y0,'o')
A=np.vander(x0)
p=np.linalg.inv(A)@y0
x1=np.linspace(-10,10,101)
plt.plot(x1,np.polyval(p,x1))

拉格朗日插值法:相对于待定系数法更为简便,首先构造一组基函数,

并令其满足以下条件,

得到n次拉格朗日插值多项式,由方程组

解的唯一性,n+1个节点的n次拉格朗日插值多项式存在且唯一。
python实现代码如下:
import numpy as np
from scipy import interpolate
import pylab as pl
x=np.linspace(-15,15,11)
y=np.sin(x)
pl.plot(x,y,'o')
x1=np.linspace(-15,15,101)
p=interpolate.lagrange(x,y)
pl.plot(x1,np.polyval(p,x1))

此外还要注意当插值次数太高产生的龙格现象。龙格现象_百度百科在计算方法中,有利用多项式对某一函数的近似逼近,计算相应的函数值。一般情况下,多项式的次数越多,需要的数据就越多,而预测也就越准确。插值次数越高,插值结果越偏离原函数的现象称为龙格现象。https://baike.baidu.com/item/%E9%BE%99%E6%A0%BC%E7%8E%B0%E8%B1%A1/5473475
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
x=np.linspace(-10,10,11)
y=np.sin(x)
x1=np.linspace(-10,10,101)
y1=np.sin(x1)
plt.plot(x1,y1,label='sinx')
f1=interpolate.interp1d(x,y,kind='quadratic')
f2=interpolate.interp1d(x,y,kind='cubic')
f3=interpolate.interp1d(x,y,kind=7)
f4=interpolate.interp1d(x,y,kind=9)
plt.plot(x1,f1(x1),label='2')
plt.plot(x1,f2(x1),label='3')
plt.plot(x1,f3(x1),label='5')
plt.plot(x1,f4(x1),label='9')
plt.legend()
plt.show()

现在我们开始讲scipy.interpolate类函数插值方法
一维插值:使用interpolate.interp1d函数插值
官方文档:
scipy.interpolate.interp1d — SciPy v1.8.1 Manual
使用时主要定义kind的类型来进行不同类别的插值
一次插值kind='inear'
二次插值kind='quadratic'
三次插值kind='cubic'
此外还有0阶插值nearest和zero方法
此两种方法使用如下:
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
x=np.linspace(0,10,11)
y=np.sin(x)
x1=np.linspace(0,10,101)
y1=np.sin(x1)
plt.plot(x1,y1)
f1=interpolate.interp1d(x,y,kind='nearest')
plt.plot(x1,f1(x1))
f2=interpolate.interp1d(x,y,kind='zero')
plt.plot(x1,f2(x1))
plt.plot(x,y)
可构成阶梯状曲线

二维插值:使用interpolate.interp2d函数插值
对模糊图像处理:
示例函数如下:

import numpy as np
import matplotlib as mpl
import pylab as pl
from scipy import interpolate
def z(x,y):
return (x+y)*np.exp(-5*(x**2+y**2))
x,y=np.mgrid[-1:1:15j,-1:1:15j]
newfunc=interpolate.interp2d(x,y,z(x,y),kind='cubic')
xnew=np.linspace(-1,1,200)
ynew=np.linspace(-1,1,200)
fnew=newfunc(xnew,ynew)
pl.subplot(121)
im1=pl.imshow(z(x,y),origin='lower',extent=[-1,1,-1,1],cmap=mpl.cm.hot)
pl.colorbar(im1)
pl.subplot(122)
im2=pl.imshow(fnew,origin='lower',extent=[-1,1,-1,1],cmap=mpl.cm.hot)
pl.colorbar(im2)
pl.show()

二维插值的三维图片展示
函数仍未上示例函数
import numpy as np
import matplotlib as mpl
from scipy import interpolate
import matplotlib.pyplot as plt
def func(x, y):
return (x + y) * np.exp(-5.0 * (x ** 2 + y ** 2))
x,y=np.mgrid[-1:1:20j,-1:1:20j]
fvals = func(x, y)
fig = plt.figure(figsize=(18,10))
ax = plt.subplot(121, projection='3d')
surf = ax.plot_surface(x, y, fvals, rstride=1, cstride=1, cmap=mpl.cm.coolwarm, linewidth=0.5,
antialiased=True)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.colorbar(surf, shrink=0.5, aspect=5,pad=0.1)
newfunc = interpolate.interp2d(x, y, fvals, kind='cubic')
xnew = np.linspace(-1, 1, 200)
ynew = np.linspace(-1, 1, 200)
fnew = newfunc(xnew, ynew)
xnew, ynew = np.meshgrid(xnew, ynew)
ax2 = plt.subplot(122, projection='3d')
surf2 = ax2.plot_surface(xnew, ynew, fnew, rstride=1, cstride=1, cmap=mpl.cm.coolwarm, linewidth=0.5, antialiased=True)
ax2.set_xlabel('xnew')
ax2.set_ylabel('ynew')
ax2.set_zlabel('znew')
plt.colorbar(surf2, shrink=0.5, aspect=5,pad=0.1)
plt.show()

大家好!我对我的:username字段进行了一个小的验证,它应该是4到30个字符。我写了一个验证::length=>{:within=>4..30,:message=>I18n.t('activerecord.errors.range')-我想显示一个错误各种错误的消息(不像,太长或太短),但这里有一个问题-我可以将最小值和最大值都传递给翻译,以便有类似的东西:用户名应该在4到30个字符之间。目前我有:range:"shouldbebetween%{count}and%{count}characters",这显然不起作用(只是为了检查)。是否可以从范围中获取这些值?谢谢大家的指教!
给定这段代码:has_many:foos,:finder_sql=#{id}部分被过早插入。我如何逃脱它? 最佳答案 在定界符两边加上单引号:has_many:foos,:finder_sql= 关于ruby-如何转义Ruby字符串插值?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/2052724/
我正在尝试使用Rails在ActionMailer中设置电子邮件地址。在它被硬编码之前,但我们现在想让它们成为ENV变量,这样我们就不需要在每次电子邮件更改时都修改代码。这是它目前的定义方式:from='"NameofPerson"'我已经尝试使用ENV['EMAIL']将电子邮件设置为环境变量,但即使使用#{ENV['EMAIL'}我也没有运气。谁能指出我正确的方向? 最佳答案 您不能在Ruby中对单引号字符串使用字符串插值。但是双引号字符串可以!from="'NameofPerson'"但是如果你想用双引号将NameofPers
有没有办法在AppleScript中实现Ruby风格的字符串插值?我需要一种灵活的方式来创建字符串模式。ruby:fn="john"=>"john"ln="doe"=>"doe"addresses=[]=>[]addresses["jdoe@company.com"]addresses["jdoe@company.com","john.doe@company.com"]苹果脚本:setfnto"john"setlnto"doe"settheAddressesto{}#jdoe@company.comcopy[somethinghere]&"@company.com"totheendof
我的目标是用散列中的值替换字符串中的键。我是这样做的:"hello%{name},todayis%{day}"%{name:"Tim",day:"Monday"}如果字符串中的键在散列中丢失:"hello%{name},todayis%{day}"%{name:"Tim",city:"Lahore"}然后它会抛出一个错误。KeyError:key{day}notfound预期结果应该是:"helloTim,todayis%{day}"or"helloTim,todayis"有人可以指导我只替换匹配的键而不抛出任何错误吗? 最佳答案
我不明白,为什么eval会这样工作:"123#{456.to_s}789"#=>"123456789"eval('123#{456.to_s}789')#=>123如何在eval中插入字符串?更新:谢谢friend们。有效。因此,如果您有一个带有#{}的字符串变量,您希望稍后对其进行评估,您应该按照以下说明进行操作:string='123#{456}789'eval("\""+string+"\"")#=>123456789或string='123#{456}789'eval('"'+string+'"')#=>123456789 最佳答案
我认为ruby只是调用方法to_s但我无法解释它是如何工作的:classFakedefto_sselfendend"#{Fake.new}"根据逻辑,由于无限递归,这应该将堆栈级别提升得太深。但它工作正常,似乎从对象调用#to_s。=>"#"但为什么呢?已添加:classFakedefto_sFake2.newendendclassFake2defto_s"Fake2#to_s"endend此代码在两种情况下的工作方式不同:puts"#{Fake.new}"=>"#"但是:putsFake.new.to_s=>"Fake2#to_s"我觉得不正常。有人可以建议在ruby解释器中
我有一个heredoc,我正在使用#{}插入一些其他字符串,但有一个实例我也想写实际文本#{some_ruby_stuff}在我的heredoc中,没有对其进行插值。有没有办法逃避#{.我试过“\”,但没有成功。虽然它逃脱了#{},它还包括“\”:>>"development\#{RAILS_ENV}\n" 最佳答案 对于无需手动转义所有潜在插值的heredoc,您可以使用单引号样式heredoc。它是这样工作的:item= 关于ruby-on-rails-如何从字符串插值中逃脱#{,我
如何在单引号内进行插值?我试过类似的方法,但有两个问题。string='textcontains"#{search.query}"'没用我需要最终字符串将动态内容用双引号括起来,如下所示:'textcontains"candy"'可能看起来很奇怪,但是gem我正在使用的需要这个。 最佳答案 如果您不想转义双引号,可以使用%{textcontains"#{search.query}"}"textcontains\"#{search.query}\"". 关于ruby-单引号内的插值,我们在
我有一个使用字符串插值来构建错误消息的Ruby脚本。p"#{vName}isnotadefinedvariable"=>'xxxisnotadefinedvariable'另一位程序员通过并试图将字符串文字外部化到一个单独的配置文件中。当然,他没有得到替换。perr_string_from_config=>'#{vName}isnotadefinedvariable'我环顾四周,但想不出比转换为sprintf字符串并使用printf更好的办法。有谁知道如何让#{}替换在Ruby脚本中对非双引号文字的字符串起作用? 最佳答案 实际上,