矩形网格上的Python 4D线性插值

矩形网格上的Python 4D线性插值,python,numpy,scipy,interpolation,Python,Numpy,Scipy,Interpolation,我需要以4维(纬度、经度、海拔和时间)线性插值温度数据。 点数相当高(360x720x50x8),我需要一种快速的方法来计算数据范围内任何时间和空间点的温度 我曾尝试使用scipy.interpolate.LinearNDInterpolator,但在矩形网格上使用Qhull进行三角剖分效率低下,需要数小时才能完成 通过阅读本文,解决方案似乎是使用标准的interp1d实现一个新的nd插值器来计算更多的数据点,然后对新数据集使用“最近邻”方法 然而,这又需要很长时间(分钟) 有没有一种快速的方法

我需要以4维(纬度、经度、海拔和时间)线性插值温度数据。
点数相当高(360x720x50x8),我需要一种快速的方法来计算数据范围内任何时间和空间点的温度

我曾尝试使用
scipy.interpolate.LinearNDInterpolator
,但在矩形网格上使用Qhull进行三角剖分效率低下,需要数小时才能完成

通过阅读本文,解决方案似乎是使用标准的
interp1d
实现一个新的nd插值器来计算更多的数据点,然后对新数据集使用“最近邻”方法

然而,这又需要很长时间(分钟)

有没有一种快速的方法可以在4维的矩形网格上插值数据,而不需要花费几分钟的时间

我想使用
interp1d
4次而不计算更高的点密度,但让用户用坐标调用,但我不知道该怎么做

否则,编写自己的4D插值器来满足我的需要会是一种选择吗

下面是我用来测试的代码:

使用
scipy.interpolate.LinearNDInterpolator

import numpy as np
from scipy.interpolate import LinearNDInterpolator

lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))

coords = np.zeros((len(lats),len(lons),len(alts),len(time),4))
coords[...,0] = lats.reshape((len(lats),1,1,1))
coords[...,1] = lons.reshape((1,len(lons),1,1))
coords[...,2] = alts.reshape((1,1,len(alts),1))
coords[...,3] = time.reshape((1,1,1,len(time)))
coords = coords.reshape((data.size,4))

interpolatedData = LinearNDInterpolator(coords,data)
使用
scipy.interpolate.interp1d

import numpy as np
from scipy.interpolate import LinearNDInterpolator

lats = np.arange(-90,90.5,0.5)
lons = np.arange(-180,180,0.5)
alts = np.arange(1,1000,21.717)
time = np.arange(8)
data = np.random.rand(len(lats)*len(lons)*len(alts)*len(time)).reshape((len(lats),len(lons),len(alts),len(time)))

interpolatedData = np.array([None, None, None, None])
interpolatedData[0] = interp1d(lats,data,axis=0)
interpolatedData[1] = interp1d(lons,data,axis=1)
interpolatedData[2] = interp1d(alts,data,axis=2)
interpolatedData[3] = interp1d(time,data,axis=3)

非常感谢你的帮助

在您链接的同一张票据中,有一个他们称之为张量积插值的示例实现,显示了嵌套对
interp1d
的递归调用的正确方法。如果为
interp1d
选择默认的
kind='linear'
参数,这相当于四次线性插值

虽然这可能足够好,但这不是线性插值,插值函数中会有高阶项,如下图所示:

这对于您所追求的可能已经足够好了,但在某些应用中,三角化、真正的分段线性插值是首选的。如果你真的需要这个,有一个简单的方法来解决qhull的慢度问题

设置了
LinearNDInterpolator
后,有两个步骤可以为给定点生成插值:

  • 找出点在哪个三角形内(在你的例子中是4D超四面体),然后
  • 使用点相对于顶点的方向作为权重进行插值
  • 您可能不想弄乱重心坐标,所以最好将其留给
    LinearNDInterpolator
    。但是你知道一些关于三角测量的事情。大多数情况下,因为你有一个规则的网格,在每个超立方体中,三角剖分是相同的。因此,要插值单个值,您可以首先确定点位于哪个子立方体中,用该立方体的16个顶点构建一个
    LinearNDInterpolator
    ,然后使用它来插值:

    from itertools import product
    
    def interpolator(coords, data, point) :
        dims = len(point)
        indices = []
        sub_coords = []
        for j in xrange(dims) :
            idx = np.digitize([point[j]], coords[j])[0]
            indices += [[idx - 1, idx]]
            sub_coords += [coords[j][indices[-1]]]
        indices = np.array([j for j in product(*indices)])
        sub_coords = np.array([j for j in product(*sub_coords)])
        sub_data = data[list(np.swapaxes(indices, 0, 1))]
        li = LinearNDInterpolator(sub_coords, sub_data)
        return li([point])[0]
    
    >>> point = np.array([12.3,-4.2, 500.5, 2.5])
    >>> interpolator((lats, lons, alts, time), data, point)
    0.386082399091
    
    这对矢量化数据不起作用,因为这需要为每个可能的子多维数据集存储一个
    线性插值器
    ,即使它可能比对整个数据集进行三角剖分更快,但速度仍然非常慢。

    是一个很好的快速插值均匀网格(所有框大小相同)。 如此看来 为了清楚的描述

    对于非均匀矩形网格,一个简单的包装器 非均匀到均匀网格的贴图/比例, 然后映射坐标。 在像您这样的4d测试用例中,每次查询大约需要1微秒:

    Intergrid: 1000000 points in a (361, 720, 47, 8) grid took 652 msec
    

    对于我使用的非常相似的东西

    现在,用户可以使用坐标调用
    插值函数

    >>> f(0,0,10,3)
    0.7085675631375401
    
    interpolingfunction
    具有很好的附加功能,例如集成和切片


    但是,我不确定插值是否是线性的。您必须查看模块源代码才能找到。

    我无法打开此地址,并且无法找到有关此软件包的足够信息

    我不知道python,但您应该查看或插入。您对其他语言有何想法?在任何语言中,简化单点的四次线性插值都应该相当容易。不,它们不是。3个维度是恒定的(.5、.5、1),但高度维度并不总是在同一点采样,因此网格在该轴上不规则。不准确。我有LAT、LON、压力和时间的常规网格上的温度数据。然而,我的目标是有一个可以这样调用的函数:getTemperature(lat、lon、ALT、time)。我所拥有的是和温度在同一网格上的高度数据,所以是相同的lat,lons,压强,时间的规则网格。现在,我实现的方法是查找给定纬度、经度和时间的两个最近高度值的压力指数。然后,它使用这些高度值和两个压力指数在温度矩阵中建立4D超四面体,并进行插值……如果网格随时间变化,是否可以使用该方法?高度点随时间变化而变化…再次感谢您的帮助!关于记法的质疑:重心是2d中3点、3d中4点、nd中n+1点的加权平均数;插值4 8。。。立方体或长方体的2^n个角称为双线性、三线性。。。多线性。@丹尼斯你的第一句话是对的,第二句话不是。
    LinearNDInterpolator
    将(超)立方体细分为不相交的(超)四面体,平铺(超)立方体,是的,当为给定点插值时,它将仅对该点周围(超)四面体的
    d+1
    顶点具有非零权重,但需要所有
    2**d
    顶点以分段线性方式插值立方体中的任何点。使用
    2**d
    顶点进行插值的方法有很多,而不是多线性,请参见以下示例:您不同意“插值4 8…”。。。
    >>> f(0,0,10,3)
    0.7085675631375401