我遇到了scipy.interpolate.interp2d
问题。
对于已排序的输入,插值正常。
当我要求得到一个未排序数组的插值时,我得到的输出就像是按SciPy内部排序的一样。为什么呢?
方法是在循环中获取插值。
下面是我的演示代码:
# !/usr/bin/env python
# -*- coding: utf-8 -*-
'''
SciPy interp2d test.
Why is the input of 2D interpolation sorted internally?
'''
import matplotlib.pyplot as plt
import scipy.interpolate as itp
import numpy as np
def fMain():
nx=11
ny=21
ax=np.linspace(0,1,nx)
mx=np.empty((nx,ny))
for i in range(ny):
mx[:,i] = ax
pass
ay=np.linspace(0,1,ny)
my=np.empty((nx,ny))
for i in range(nx): # can I do this without loop?
my[i,:] = ay
pass
mz=np.empty((nx,ny))
mz=mx**2 + my**3
f2Di = itp.interp2d( mx, my, mz, kind='linear')
#this provides identical results, ok
#f2Di = itp.interp2d( ax, ay, mz.transpose(), kind='linear')
if True :
# just to check the interpolation
mzi = f2Di(ax,ay)
fig = plt.figure()
axis = fig.add_subplot(projection='3d')
axis.plot_wireframe( mx, my, mz )
axis.scatter(mx, my, mzi.transpose(), marker="o",color="red")
axis.set_xlabel("x")
axis.set_ylabel("y")
axis.set_zlabel("z")
plt.tight_layout()
plt.show()
plt.close()
pass
if True:
y = 0.5
az = f2Di( ax , y )
axf=np.flip(ax)
azf1 = f2Di( axf , y )
azf2 = np.empty(nx)
for i in range(nx):
azf2[i] = f2Di( axf[i] , y )
pass
plt.plot(ax,az,label="Normal",linewidth=3,linestyle="dashed")
plt.plot(axf,azf1,label="Reversed")
plt.plot(axf,azf2,label="Reversed loop")
plt.legend()
plt.xlabel("x")
plt.ylabel("z")
plt.tight_layout()
plt.show()
plt.close()
pass
pass
if __name__ == "__main__":
fMain()
pass
2条答案
按热度按时间0wi1tuuw1#
要回答另一个问题(来自代码中的注解):
(and对于
ay
类似)。我可以循环执行此操作吗?
是的(技术上是不可以的,因为在引擎盖下面会有一个C循环,但实际上是可以的)。使用
numpy.tile
:而下面的
np.empty
没有意义:您分配内存,但立即将变量(重新)赋值为另一个值:这也是为什么
np.empty
从for-replacement代码中消失的原因。qkf9rpyu2#
有一个内置的函数可以生成像
mx,my
这样的网格:或者,您可以使用广播分配这些值
interp2d
文档说输入数组是扁平的,即使输入是二维的,并且x,y
可以是ax,ay
中的坐标;它们不必从整个网格中构建。因此,设置f2Di
的两种方法是等效的。使用
f2Di(x,y)
的完整文档https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.call.html#scipy.interpolate.interp2d.call
它明确指出输入
x,y
必须排序,否则它将为您执行此操作。一次插值:
另一个输入相反:
正如您所注意到的,并试图用大量绘图代码来显示,结果是相同的-输入在用于插值之前已经排序。
如果我错误地告诉它坐标已排序:
请注意,这个错误是由
_fitpack
中的一个函数引发的。这个名字暗示着它使用了某种编译的插值代码,一个可能用C或Fortran编写的库。我不是一个开发人员,但我可以想象,在假设输入是排序的情况下编写这样的代码是最容易的。这样的共享库在对输入有明确和相对简单的期望时工作得最好。