线性分段数据的Numpy scipy 2D插值

8e2ybdfx  于 2024-01-09  发布在  其他
关注(0)|答案(3)|浏览(198)

我有几点:

  1. points = np.array([[0, 105],[5000, 105],[0, 135],[5000, 135],[0, 165],[5000, 165]])

字符串
和价值观

  1. values = np.array([[300, 380, 300, 390, 300, 400]]).transpose()


我尝试插值的输入

  1. xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])


具有双线性插值的预期结果(参考:https://en.wikipedia.org/wiki/Bilinear_interpolation

  1. [340, 343.3333, 345, 347.5, 350]


我的工作为第二个例子使用双线性插值

  1. x1=2500, y1=105 giving z1=340
  2. x2=2500, y2=135 giving z2=345
  3. Hence for x3=2500, y3=125 gives z3=343.3333


但随着

  1. gd = griddata(points, values, xi, method='linear', rescale=True)


我正在得到结果

  1. [340, 345, 345, 345, 350]


我一定是错过了一些简单的东西在这里,但没有得到任何尝试多种不同的方法。

g0czyy6m

g0czyy6m1#

如果您正确地提供了数据,则可以使用scipy.interpolate.interpn完成此操作。(对于2D情况)。然后以与网格对应的格式定义值,这是2D情况下np.meshgrid(x, y, indexing="ij")的结果。请确保严格按升序或降序提供x和y,否则interpn将抛出错误。

  1. import numpy as np
  2. from scipy.interpolate import interpn
  3. x = np.array([0, 5000])
  4. y = np.array([105, 135, 165])
  5. # data corresponds to (x, y) given by np.meshgrid(x, y, indexing="ij")
  6. values = np.array([[300, 300, 300],
  7. [380, 390, 400]])
  8. xi = np.array([[2500, 105],
  9. [2500, 125],
  10. [2500, 135],
  11. [2500, 150],
  12. [2500, 165]])
  13. interpolated = interpn((x, y), values, xi) # array([340., 343.33333333, 345., 347.5, 350.])

字符串
这里它是作为一个函数编写的,尽管它没有一般使用所需的所有功能,即检查输入,确保正确的数据库等。

  1. import numpy as np
  2. from scipy.interpolate import interpn
  3. # moved one of the points and values to show it works with both unsorted
  4. # x and y values
  5. points = np.array([[0, 105],[5000, 105],[5000, 135],[0, 165],[5000, 165],[0, 135]])
  6. values = np.array([[300, 380, 390, 300, 400, 300]]).T
  7. xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])
  8. def bilinear_interpolation(points, values, xi):
  9. p = points.copy()
  10. v = values.copy()
  11. # sorting the points to ensure ascending order
  12. ysorted = np.argsort(p[:,1])
  13. p = p[ysorted]
  14. v = v[ysorted]
  15. xsorted = np.argsort(p[:,0])
  16. p = p[xsorted]
  17. v = v[xsorted]
  18. x = np.unique(p[:,0])
  19. y = np.unique(p[:,1])
  20. v = v.reshape(x.size, y.size)
  21. return interpn((x, y), v, xi)
  22. interpolated = bilinear_interpolation(points, values, xi)

展开查看全部
ukdjmx9f

ukdjmx9f2#

我运行代码,得到和你一样的结果。

  1. import matplotlib.pyplot as plt
  2. from matplotlib import cm
  3. from matplotlib.ticker import LinearLocator
  4. import numpy as np
  5. from scipy.interpolate import griddata
  6. points = np.array([[0, 105], [5000, 105], [0, 135], [5000, 135], [0, 165], [5000, 165]])
  7. values = np.array([[300, 380, 300, 390, 300, 400]]).transpose()
  8. xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])
  9. gd = griddata(points, values, xi, method='linear', rescale=True)
  10. print(gd)
  11. fig = plt.figure()
  12. ax = fig.add_subplot(111, projection='3d')
  13. # Plot the surface
  14. ax.plot_trisurf(points[:,0], points[:,1], values.flatten(), cmap=cm.get_cmap('Blues'), linewidth=0.2)
  15. # Customize the axes
  16. ax.set_xlabel('X')
  17. ax.set_ylabel('Y')
  18. ax.set_zlabel('Z')
  19. ax.xaxis.set_major_locator(LinearLocator(3))
  20. ax.yaxis.set_major_locator(LinearLocator(3))
  21. ax.zaxis.set_major_locator(LinearLocator(5))
  22. plt.show()

字符串
结果是:

  1. [[340.]
  2. [345.]
  3. [345.]
  4. [345.]
  5. [350.]]


如果我把linear改为cubic,我得到:

  1. [[340.46073832]
  2. [343.60340822]
  3. [345.00000255]
  4. [347.06944598]
  5. [349.53926443]]


这是更接近你所期望的.所以它看起来像一个插值方法的问题。
它看起来就像你在这个曲面上插值:


的数据
如果你能展示你是如何达到预期结果的,那么这将是有帮助的。

展开查看全部
up9lanfz

up9lanfz3#

这是一个很长的问题:你可以写一个函数来完成同样的任务:

  1. import numpy as np
  2. def interpolate(p, points, values):
  3. xpoint, ypoint = np.unique(points[:,0]), np.unique(points[:,1])
  4. z = values.reshape(ypoint.size, xpoint.size).T
  5. x, y = p[:,0], p[:,1]
  6. xind = np.searchsorted(xpoint, x)
  7. yind = np.searchsorted(ypoint, y)
  8. xind_min = np.maximum(xind - 1, 0)
  9. yind_min = np.maximum(yind - 1, 0)
  10. Q11 = z[xind_min, yind_min]
  11. Q12 = z[xind_min, yind]
  12. Q21 = z[xind, yind_min]
  13. Q22 = z[xind, yind]
  14. x1, x2 = xpoint[xind_min], xpoint[xind]
  15. y1, y2 = ypoint[yind_min], ypoint[yind]
  16. x_diff = np.where(x2 > x1, x2 - x1, 1)
  17. xy1 = ((x2 - x)*Q11 + (x - x1)*Q21) / x_diff
  18. xy2 = ((x2 - x)*Q12 + (x - x1)*Q22) / x_diff
  19. y_diff = np.where(y2 > y1, y2 - y1, 1)
  20. res = ((y2 - y) * xy1 + (y - y1) * xy2)/y_diff
  21. equalX, equalY = x2 == x, y2 == y
  22. equalXY = equalX & equalY
  23. res[equalXY] = z[xind[equalXY], yind[equalXY]]
  24. res[equalX & ~equalY] = z.mean(1)[xind[equalX & ~equalY]]
  25. res[~equalX & equalY] = z.mean(0)[yind[~equalX & equalY]]
  26. return res
  27. points = np.array([[0, 105],[5000, 105],[0, 135],[5000, 135],[0, 165],[5000, 165]])
  28. values = np.array([[300, 380, 300, 390, 300, 400]]).transpose()
  29. xi = np.array([[2500, 105],[2500, 125],[2500, 135],[2500, 150],[2500, 165]])
  30. interpolate(xi, points, values)
  31. array([340. , 343.33333333, 345. , 347.5 ,
  32. 350. ])

字符串

展开查看全部

相关问题