在python中以3D模式进行样条插值 [英] Spline interpolation in 3D in python

查看:235
本文介绍了在python中以3D模式进行样条插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搜索等效的Matlab命令

I am searching the equivalent Matlab command

Vq = interp3(X,Y,Z,V,Xq,Yq,Zq)

在Python中.在Matlab中,我可以使用'spline'插值方法,在python中找不到3D数据.存在scipy.interpolate.griddata,但没有用于3D数据的样条线.

in Python. In Matlab I can use the method 'spline' interpolation, which I can not find in python for 3D data. There exists scipy.interpolate.griddata, but it doesn't have the option spline for 3D data.

我要插入的数据是3D矩阵(51x51x51),该矩阵有规律地分布在3D网格上.

The data I want to interpolate is a 3D matrix (51x51x51), which is regularly distributed on a 3D grid.

scipy.interpolate.Rbf可能是选项,但我不起作用:

scipy.interpolate.Rbf may be the option, but I don't get it working:

xi = yi = zi = np.linspace(1, 132651, 132651) interp = scipy.interpolate.Rbf(xi, yi, zi, data, function='cubic')

xi = yi = zi = np.linspace(1, 132651, 132651) interp = scipy.interpolate.Rbf(xi, yi, zi, data, function='cubic')

导致内存错误.

我想要的最小示例(无插值): Matlab代码

A minimal example of what I want (without interpolation): Matlab code

v=rand([51,51,51]);
isosurface (v, 0.3);

为简单起见,在此示例中,我使用随机数据.我要绘制等值面图(特别是费米曲面图).由于某些结构非常小,因此需要51x51x51的高网格分辨率.

For simplicity, I use random data in this example. I want to make isosurface plots (in particular, Fermi surface plots). Since some structures are very small, a high grid resolution of 51x51x51 is needed.

进一步的评论:矩阵中的数据集彼此独立,z(或第3个分量)不是x和y的函数.

A further comment: The data set in the matrix is independent from each other, z (or the 3rd component) is NOT a function of x and y.

推荐答案

可以使用scipy.interpolate.Rbf进行3维以上的样条插值.出于绘图目的,您可以使用较小的分辨率(1000点是一个很好的经验法则),并且当您要评估样条线时,可以在大于132000的点上插值而不会出现问题(请参见下面的示例).

Spline interpolation on for 3+ dimensions can be done using scipy.interpolate.Rbf as your described. For plotting purposes you can use a smaller resolution (1000 points is a good rule of thumb), and when you want to evaluate your spline, you can interpolate on much greater than 132000 points without problem (see example below).

您可以针对在matlab中尝试执行的操作添加最小,完整和可验证的示例吗?这将解释为什么您需要创建一个分辨率为132000点的网格空间.另外,请注意,存在维数的诅咒. Matlab使用三次样条或分段多项式,由于过度拟合可能会造成危险.我建议您使用一种更明智的方法来对51个数据点进行训练并将其应用于132000+个数据点. 是多项式曲线拟合和模型选择的一个很好的例子. >

示例:

生成数据:

Can you add a Minimal, Complete, and Verifiable example for what you are trying to do in matlab? This will explain why do you need to create a grid space with a resolution of 132000 points. Also, please note, there is a curse of dimensionality. Matlab uses a cubic spline or a piecewise polynomial which can be dangerous due to overfitting. I recommend you used a more sane method for training on 51 datapoints and applying to 132000+ datapoints. This is a great example on polynomial curve fitting and model selection.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d

%matplotlib inline
import random
# set seed to reproducible
random.seed(1)
data_size = 51
max_value_range = 132651
x = np.array([random.random()*max_value_range for p in range(0,data_size)])
y = np.array([random.random()*max_value_range for p in range(0,data_size)])
z = 2*x*x*x + np.sqrt(y)*y + random.random()
fig = plt.figure(figsize=(10,6))
ax = axes3d.Axes3D(fig)
ax.scatter3D(x,y,z, c='r')

x_grid = np.linspace(0, 132651, 1000*len(x))
y_grid = np.linspace(0, 132651, 1000*len(y))
B1, B2 = np.meshgrid(x_grid, y_grid, indexing='xy')
Z = np.zeros((x.size, z.size))

import scipy as sp
import scipy.interpolate
spline = sp.interpolate.Rbf(x,y,z,function='thin_plate',smooth=5, episilon=5)

Z = spline(B1,B2)
fig = plt.figure(figsize=(10,6))
ax = axes3d.Axes3D(fig)
ax.plot_wireframe(B1, B2, Z)
ax.plot_surface(B1, B2, Z,alpha=0.2)
ax.scatter3D(x,y,z, c='r')

predict_data_size = 132000
x_predict = np.array([random.random()*max_value_range for p in range(0,predict_data_size)])
y_predict = np.array([random.random()*max_value_range for p in range(0,predict_data_size)])
z_predict = spline(x_predict, y_predict)
fig = plt.figure(figsize=(10,6))
ax = axes3d.Axes3D(fig)
ax.plot_wireframe(B1, B2, Z)
ax.plot_surface(B1, B2, Z,alpha=0.2)
ax.scatter3D(x_predict,y_predict,z_predict, c='r')

这篇关于在python中以3D模式进行样条插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆