首页 > 编程问答 >Python griddata() 和 Matlab griddata():某些网格点的结果不同

Python griddata() 和 Matlab griddata():某些网格点的结果不同

时间:2024-07-27 05:29:32浏览次数:8  
标签:python matlab scipy interpolation delaunay

在将一些(相当大的物理)Matlab 代码转换为 Python 时,我偶然发现了这种情况。当对相同的二维离散数据进行插值时,Python/Scipy 的 griddata() 函数给出的结果与 Matlab 的对应函数不同。 griddata() Matlab 示例代码:

Python 示例代码:

% Sample points (x,y): 7x5=35 points
points = [-3., -2.; -2.25, -2.; -1.5, -2.; -0.75, -2.; 0., -2.; 0.75, -2.; 1.5, -2.;
    -3., -1.25; -2.25, -1.25; -1.5, -1.25; -0.75, -1.25; 0., -1.25; 0.75, -1.25; 1.5, -1.25;
    -3., -0.5; -2.25, -0.5; -1.5, -0.5; -0.75, -0.5; 0., -0.5; 0.75, -0.5; 1.5, -0.5;
    -3., 0.25; -2.25, 0.25; -1.5, 0.25; -0.75, 0.25; 0., 0.25; 0.75, 0.25; 1.5, 0.25;
    -3., 1.; -2.25, 1.; -1.5, 1.; -0.75, 1.; 0., 1.; 0.75, 1.; 1.5, 1.]

% Data values at the sample points: 35 values
values = [0.12702104; -0.24534877; -0.08879096; 0.13749533; 0.2431933; -0.01159269; 0.11705169;
    0.10039714; 0.23370454; 0.0020298; -0.05512349; -0.11208613; -0.09864074; 0.45360373;
    -0.10414895; -0.18303173; 0.39306646; 0.05457107; -0.19024738; 0.06828192; 0.29422425;
    -0.18672513; -0.23610061; 0.48881179; -0.09731334; -0.05470424; 0.26214565; -0.17978073,
    -0.10337649; 0.10246465; 0.24676284; -0.05835531; 0.06804471; -0.34589734; -0.34035067];

% Grid points to interpolate at: 12x12 points
[X,Y] = meshgrid(linspace(-2,1.2,12), linspace(-1.75,0.75,12));

% Interpolation
Z = griddata(points(:,1), points(:,2), values, X, Y, "linear");

这是 Matlab 输出。

import numpy as np
import scipy

# Sample points (x, y): 7x5 = 35 points
points = np.array([
    [-3., -2.], [-2.25, -2.], [-1.5, -2.], [-0.75, -2.], [0., -2.], [0.75, -2.], [1.5, -2.],
    [-3., -1.25], [-2.25, -1.25], [-1.5, -1.25], [-0.75, -1.25], [0., -1.25], [0.75, -1.25], [1.5, -1.25],
    [-3., -0.5], [-2.25, -0.5], [-1.5, -0.5], [-0.75, -0.5], [0., -0.5], [0.75, -0.5], [1.5, -0.5],
    [-3., 0.25], [-2.25, 0.25], [-1.5, 0.25], [-0.75, 0.25], [0., 0.25], [0.75, 0.25], [1.5, 0.25],
    [-3., 1.], [-2.25, 1.], [-1.5, 1.], [-0.75, 1.], [0., 1.], [0.75, 1.], [1.5, 1.]
])

# Data values at the sample points: 35 values
values = np.array([
    0.12702104, -0.24534877, -0.08879096, 0.13749533, 0.2431933, -0.01159269, 0.11705169,
    0.10039714, 0.23370454, 0.0020298, -0.05512349, -0.11208613, -0.09864074, 0.45360373,
    -0.10414895, -0.18303173, 0.39306646, 0.05457107, -0.19024738, 0.06828192, 0.29422425,
    -0.18672513, -0.23610061, 0.48881179, -0.09731334, -0.05470424, 0.26214565, -0.17978073,
    -0.10337649, 0.10246465, 0.24676284, -0.05835531, 0.06804471, -0.34589734, -0.34035067
])

# Interpolation grid: 12x12 points 
x = np.linspace(-2, 1.2, 12)
y = np.linspace(-1.75, 0.75, 12)
X, Y = np.meshgrid(x, y)

# Interpolation
Z = scipy.interpolate.griddata(points, values, (X, Y), method='linear')

并且这是Python 输出。

输出值差异很大。然后我尝试使用

中的 Delaunay 三角测量工具和 scipy.spatial 功能来绕过它: scipy.interpolate.LinearNDInterpolator 仍然没有运气。结果不一样。这会是什么原因呢?我们如何从 Scipy 的

# # Perform Delaunay triangulation
tri = Delaunay(points, qhull_options='Qbb Qc') #Qt is always enabled
# # Interpolation function
interp = sp.LinearNDInterpolator(points, values)
ZZ = interp(X, Y)

函数中得到相同的结果? griddata() function?


Matlab 和 Python 的 griddata 中的三角剖分方案差异

Matlab 和 Python 的 griddata 函数使用不同的默认三角剖分方案进行线性插值,这会导致在某些网格点处出现不同的结果。

Matlab

  • Matlab 的 griddata 默认使用 Delaunay 三角剖分

Python

  • Python 的 scipy.interpolate.griddata 默认使用 Qhull 库 进行三角剖分。虽然 Qhull 也能执行 Delaunay 三角剖分,但它使用的算法和参数与 Matlab 不同。

解决方法

要使 Python 的 griddata 产生与 Matlab 相似的结果,可以指定使用 scipy.spatial.Delaunay 函数进行三角剖分,并将其传递给 scipy.interpolate.LinearNDInterpolator

import numpy as np
from scipy.spatial import Delaunay
from scipy.interpolate import LinearNDInterpolator

# ...(的现有代码)...

# 执行 Delaunay 三角剖分
tri = Delaunay(points)  # 使用与 Matlab 相同的三角剖分方案

# 插值函数
interp = LinearNDInterpolator(tri, values)
ZZ = interp(X, Y)

其他注意事项

  • 即使使用相同的三角剖分方案,由于浮点运算的细微差异,Matlab 和 Python 的结果也可能略有不同。
  • 对于大型数据集, LinearNDInterpolator 可能比 griddata 更快。
  • 还可以探索 scipy.interpolate 模块中的其他插值方法,例如 CloughTocher2DInterpolator (对于平滑插值)或 Rbf (对于径向基函数插值)。

通过使用 scipy.spatial.Delaunay 显式指定三角剖分方案,可以使 Python 代码的行为更接近 Matlab 的 griddata 函数,并获得更一致的插值结果。

标签:python,matlab,scipy,interpolation,delaunay
From: 78798517

相关文章

  • Ebay Python SDK 仅在特定项目类别上返回错误
    我在一个项目中使用ebaySDK一段时间了。最近我尝试导入一些商品,例如手表、手机壳等...并且我使用了eBay自己通过eBay返回的英国商店页面上的类别ID他们的“get_category_suggestions”API端点,但eBay似乎有选择地决定拒绝某些项目并引发服务器错误!为了测试,我做了......
  • 使用特定的Python版本(MacOS)制作virtualenv
    我安装了brew,python3(默认和最新版本)和pip3,pyenv。TensorFlow现在不支持python3.7,所以我听说我应该制作一个独立运行3.6或更低版本的virtualenv。我安装了python3.6.7bypyenvinstall3.6.7但无法制作virtualenv-p3.6.7(mydir)因为3.6.7不在P......
  • 使用Python去除图像中的线条
    我正在尝试使用Python和cv2、numpy、skimage等从黑白图像中删除“阴影线”(如果图像中存在“阴影线”)。本质上,我的图像可以有1或2条曲线,如下例所示。但每条线都有一条1-5像素外的阴影线,需要删除。我怎样才能在Python中做到这一点?原始......
  • Python 和 OpenCV:如何裁剪半成形边界框
    我有一个为无网格表创建网格线的脚本:脚本之前:脚本之后:是否有一种简单的方法,使用OpenCV来裁剪“脚本之后”图像,使其仅包含四边边界框?示例输出:编辑:我目前正在研究一种解决方案,该解决方案可以找到垂直/水平方向的第一条/最后一条......
  • 使用类型提示将 Python 转换为 Cython
    类型提示现在在Python3.5版本中可用。在规范(PEP484)中,目标(和非目标)被明确暴露:#RationaleandGoals此PEP旨在为类型注释提供标准语法,开放Python代码更容易静态分析和重构、潜在的运行时类型检查以及(也许在某些情况下)利用类型信息生成代码。......
  • 在 Python 类型提示中区分 PySpark 和 Pandas DataFrame (PyCharm)
    在PyCharm中,如果使用apyspark.sql.DataFrame代替pandas.DataFrame,类型提示似乎不会触发警告,反之亦然。例如以下代码根本不会生成任何警告:frompyspark.sqlimportDataFrameasSparkDataFramefrompandasimportDataFrameasPandasDataFramedef......
  • 如何在Python中继承类型提示?
    所以我的问题是,当我有一个A类型的类来做事情并且我使用这些函数作为subclass(B)时,它们仍然是类A的类型,并且不接受我的类B对象作为参数或作为函数签名。我的问题简化了:fromtypingimportTypeVar,Generic,CallableT=TypeVar('T'......
  • Python - 如何传递类对象的函数参数类型(打字)
    我想python3.7附带了(不确定),不仅可以将变量名传递给函数,还可以传递变量的类型。我想知道的是是否有可能传递特定类的类型。以同样的方式传递:deffoo_func(i:int)->None:pass如果我有一个类,让我们说:classfoo_class(object):pass我如何转换fo......
  • 基于kalman滤波的UAV三维轨迹跟踪算法matlab仿真
    1.程序功能描述      使用卡尔曼滤波对UAV在三维空间场景中的运动轨迹进行预测和估计,最后输出预测轨迹,估计轨迹以及三维空间轨迹估计结果。 2.测试软件版本以及运行结果展示MATLAB2022a版本运行  3.核心程序  fork=1:length(X_direct)-1%第一个......
  • 使用 Python 构建简单 REST API
    使用Python构建简单RESTAPI1.概述本技术文档旨在指导开发者使用Python框架Flask构建一个基本的RESTAPI。通过学习本指南,您将掌握创建、读取、更新和删除(CRUD)操作的基本知识,并能够使用Python构建自己的API。2.安装依赖首先,您需要确保已安装Python和Flask......