python/scipy中的多元样条插值? [英] Multivariate spline interpolation in python/scipy?

查看:379
本文介绍了python/scipy中的多元样条插值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有库模块或其他简单的方法可以在python中实现多元样条插值?

Is there a library module or other straightforward way to implement multivariate spline interpolation in python?

具体来说,我在规则排列的三维网格上有一组标量数据,需要在散布在整个域中的少量点处进行插值.对于两个维度,我一直在使用 scipy.interpolate.RectBivariateSpline ,而我本质上是在寻找将其扩展到三维数据的方法.

Specifically, I have a set of scalar data on a regularly-spaced three-dimensional grid which I need to interpolate at a small number of points scattered throughout the domain. For two dimensions, I have been using scipy.interpolate.RectBivariateSpline, and I'm essentially looking for an extension of that to three-dimensional data.

我发现的N维插值例程还不够好:我更喜欢样条曲线,而不是

The N-dimensional interpolation routines I have found are not quite good enough: I would prefer splines over LinearNDInterpolator for smoothness, and I have far too many data points (often over one million) for, e.g., a radial basis function to work.

如果有人知道可以执行此操作的python库,或者可能会调用或移植另一种语言的python库,我将不胜感激.

If anyone knows of a python library that can do this, or perhaps one in another language that I could call or port, I'd really appreciate it.

推荐答案

如果我正确地理解了您的问题,那么您输入的观测"数据会定期网格化吗?

If I'm understanding your question correctly, your input "observation" data is regularly gridded?

如果是这样, scipy.ndimage.map_coordinates 完全满足您的要求.

If so, scipy.ndimage.map_coordinates does exactly what you want.

乍一看有点难理解,但是从本质上讲,您只是向它提供了一系列要在像素/体素/n维指数坐标中插值网格值的坐标.

It's a bit hard to understand at first pass, but essentially, you just feed it a sequence of coordinates that you want to interpolate the values of the grid at in pixel/voxel/n-dimensional-index coordinates.

作为2D示例:

import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt

# Note that the output interpolated coords will be the same dtype as your input
# data.  If we have an array of ints, and we want floating point precision in
# the output interpolated points, we need to cast the array as floats
data = np.arange(40).reshape((8,5)).astype(np.float)

# I'm writing these as row, column pairs for clarity...
coords = np.array([[1.2, 3.5], [6.7, 2.5], [7.9, 3.5], [3.5, 3.5]])
# However, map_coordinates expects the transpose of this
coords = coords.T

# The "mode" kwarg here just controls how the boundaries are treated
# mode='nearest' is _not_ nearest neighbor interpolation, it just uses the
# value of the nearest cell if the point lies outside the grid.  The default is
# to treat the values outside the grid as zero, which can cause some edge
# effects if you're interpolating points near the edge
# The "order" kwarg controls the order of the splines used. The default is 
# cubic splines, order=3
zi = ndimage.map_coordinates(data, coords, order=3, mode='nearest')

row, column = coords
nrows, ncols = data.shape
im = plt.imshow(data, interpolation='nearest', extent=[0, ncols, nrows, 0])
plt.colorbar(im)
plt.scatter(column, row, c=zi, vmin=data.min(), vmax=data.max())
for r, c, z in zip(row, column, zi):
    plt.annotate('%0.3f' % z, (c,r), xytext=(-10,10), textcoords='offset points',
            arrowprops=dict(arrowstyle='->'), ha='right')
plt.show()

要在n维中执行此操作,我们只需要传递适当大小的数组即可:

To do this in n-dimensions, we just need to pass in the appropriate sized arrays:

import numpy as np
from scipy import ndimage

data = np.arange(3*5*9).reshape((3,5,9)).astype(np.float)
coords = np.array([[1.2, 3.5, 7.8], [0.5, 0.5, 6.8]])
zi = ndimage.map_coordinates(data, coords.T)

就扩展和内存使用而言,如果您使用的顺序> 1(即非线性插值),则map_coordinates将创建数组的过滤副本.如果只想在极少的点进行插值,则这是相当大的开销.但是,它不会随着要插入的点数而增加.只要有足够的RAM用于输入数据数组的单个临时副本,就可以了.

As far as scaling and memory usage goes, map_coordinates will create a filtered copy of the array if you're using an order > 1 (i.e. not linear interpolation). If you just want to interpolate at a very small number of points, this is a rather large overhead. It doesn't increase with the number points you want to interpolate at, however. As long as have enough RAM for a single temporary copy of your input data array, you'll be fine.

如果无法将数据副本存储在内存中,则可以a)指定prefilter=Falseorder=1并使用线性插值,或者b)使用ndimage.spline_filter用过滤后的版本替换原始数据,然后使用prefilter=False调用map_coordinates.

If you can't store a copy of your data in memory, you can either a) specify prefilter=False and order=1 and use linear interpolation, or b) replace your original data with a filtered version using ndimage.spline_filter, and then call map_coordinates with prefilter=False.

即使您有足够的内存,如果需要多次调用map_coordinates(例如,交互式使用等),则保持过滤后的数据集也可以大大提高速度.

Even if you have enough ram, keeping the filtered dataset around can be a big speedup if you need to call map_coordinates multiple times (e.g. interactive use, etc).

这篇关于python/scipy中的多元样条插值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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