如何在python中将2d插值函数显示为矩阵?

如何在python中将2d插值函数显示为矩阵?,python,matrix,2d,interpolation,Python,Matrix,2d,Interpolation,我环顾了很多地方,但很难找到答案。基本上,当一个插值v->w时,通常会使用许多插值函数中的一个。但是我想得到相应的矩阵Av=w 在我的例子中,w是一个200x200矩阵,v是w的一个随机子集,有一半的点。我真的不喜欢花哨的数学,它可以像用距离平方加权已知点那样简单。我已经尝试过用一些for循环来实现这一切,但它只适用于较小的值。但也许这有助于解释我的问题 from random import sample def testScatter(xbig, ybig): Num

我环顾了很多地方,但很难找到答案。基本上,当一个插值v->w时,通常会使用许多插值函数中的一个。但是我想得到相应的矩阵Av=w

在我的例子中,w是一个200x200矩阵,v是w的一个随机子集,有一半的点。我真的不喜欢花哨的数学,它可以像用距离平方加权已知点那样简单。我已经尝试过用一些for循环来实现这一切,但它只适用于较小的值。但也许这有助于解释我的问题

from random import sample

    def testScatter(xbig, ybig):
        NumberOfPoints = int(xbig * ybig / 2) #half as many points as in full Sample

    #choose random coordinates
    Index = sample(range(xbig * ybig),NumberOfPoints)
    IndexYScatter = np.remainder(Index,  xbig)
    IndexXScatter = np.array((Index - IndexYScatter) / xbig, dtype=int)

    InterpolationMatrix = np.zeros((xbig * ybig , NumberOfPoints), dtype=np.float32)
    WeightingSum = np.zeros(xbig * ybig )
    coordsSamplePoints = []
    for i in range(NumberOfPoints): #first set all the given points (no need to interpolate)
        coordsSamplePoints.append(IndexYScatter[i] + xbig * IndexXScatter[i])
        InterpolationMatrix[coordsSamplePoints[i], i] = 1
        WeightingSum[coordsSamplePoints[i]] = 1
    
    for x in range(xbig * ybig): #now comes the interpolation
        if x not in coordsSamplePoints:
            YIndexInterpol = x % xbig      #xcoord in interpolated matrix
            XIndexInterpol = (x - YIndexInterpol) / xbig  #ycoord in interp. matrix
            for y in range(NumberOfPoints):
                XIndexScatter = IndexXScatter[y]
                YIndexScatter = IndexYScatter[y]
                distanceSquared = (np.float32(YIndexInterpol) - np.float32(YIndexScatter))**2+(np.float32(XIndexInterpol) - np.float32(XIndexScatter))**2
                InterpolationMatrix[x,y] = 1/distanceSquared
                WeightingSum[x] += InterpolationMatrix[x,y]

    return InterpolationMatrix/ WeightingSum[:,None] , IndexXScatter, IndexYScatter

您需要花一些时间来处理Numpy文档,从顶部开始,逐步向下。学习这里的答案,了解使用Numpy数组时如何对操作进行矢量化的问题,会对您有所帮助。如果您发现您正在迭代索引并使用Numpy数组执行calc,那么可能有更好的方法

第一次切割…
第一个for循环可以替换为:

coordsSamplePoints = IndexYScatter + (xbig * IndexXScatter)
InterpolationMatrix[coordsSamplePoints,np.arange(coordsSamplePoints.shape[0])] = 1
WeightingSum[coordsSamplePoints] = 1
...
    space = np.arange(xbig * ybig)
    mask = ~(space == cSS[:,None]).any(0)
    iP = space[mask]    # points to interpolate
    yIndices = iP % xbig
    xIndices = (iP - yIndices) / xbig
    ...
这主要利用了和-应该阅读完整的索引教程

您可以通过增强函数和执行for循环以及Numpy方法来测试这一点,然后比较结果

...
    IM = InterpolationMatrix.copy()
    WS = WeightingSum.copy()
    for i in range(NumberOfPoints): #first set all the given points (no need to interpolate)
        coordsSamplePoints.append(IndexYScatter[i] + xbig * IndexXScatter[i])
        InterpolationMatrix[coordsSamplePoints[i], i] = 1
        WeightingSum[coordsSamplePoints[i]] = 1
    cSS = IndexYScatter + (xbig * IndexXScatter)
    IM[cSS,np.arange(cSS.shape[0])] = 1
    WS[cSS] = 1
    # TEST Validity
    print((cSS == coordsSamplePoints).all(),
          (IM == InterpolationMatrix).all(),
          (WS == WeightingSum).all())
...        

外环:

...
    for x in range(xbig * ybig): #now comes the interpolation
        if x not in coordsSamplePoints:
            YIndexInterpol = x % xbig      #xcoord in interpolated matrix
            XIndexInterpol = (x - YIndexInterpol) / xbig  #ycoord in interp. matrix
            ...
可替换为:

coordsSamplePoints = IndexYScatter + (xbig * IndexXScatter)
InterpolationMatrix[coordsSamplePoints,np.arange(coordsSamplePoints.shape[0])] = 1
WeightingSum[coordsSamplePoints] = 1
...
    space = np.arange(xbig * ybig)
    mask = ~(space == cSS[:,None]).any(0)
    iP = space[mask]    # points to interpolate
    yIndices = iP % xbig
    xIndices = (iP - yIndices) / xbig
    ...
完整解决方案:

import random
import numpy as np
def testScatter(xbig, ybig):
    NumberOfPoints = int(xbig * ybig / 2) #half as many points as in full Sample

    #choose random coordinates
    Index = random.sample(range(xbig * ybig),NumberOfPoints)
    IndexYScatter = np.remainder(Index,  xbig)
    IndexXScatter = np.array((Index - IndexYScatter) / xbig, dtype=int)
    InterpolationMatrix = np.zeros((xbig * ybig , NumberOfPoints), dtype=np.float32)
    WeightingSum = np.zeros(xbig * ybig )
    
    coordsSamplePoints = IndexYScatter + (xbig * IndexXScatter)
    InterpolationMatrix[coordsSamplePoints,np.arange(coordsSamplePoints.shape[0])] = 1
    WeightingSum[coordsSamplePoints] = 1

    IM = InterpolationMatrix
    cSS = coordsSamplePoints
    WS = WeightingSum

    space = np.arange(xbig * ybig)
    mask = ~(space == cSS[:,None]).any(0)
    iP = space[mask]    # points to interpolate
    yIndices = iP % xbig 
    xIndices = (iP - yIndices) / xbig
    dSquared = ((yIndices[:,None] - IndexYScatter) ** 2) + ((xIndices[:,None] - IndexXScatter) ** 2)
    IM[iP,:] = 1/dSquared
    WS[iP] = IM[iP,:].sum(1)

    return IM / WS[:,None], IndexXScatter, IndexYScatter
我得到了大约200倍的改善,这比你原来的(100100)的论点。可能还有其他一些小的改进,但它们不会显著影响执行时间



是另一项必须具备的Numpy技能。

你在问什么?是否有人知道加快速度的方法,或者只是在过程中犯了一个错误。对不起,我对编程很陌生。你们对函数实现的数学有信心吗?当您使用已知输入测试函数时,它是否产生正确的结果?你能用语言解释你的功能是什么吗?什么是样本(范围(xbig*ybig),点数)-<代码>名称错误:未定义名称“sample”很抱歉,我添加了实现它的行。这是随机的。当在9x9矩阵上测试时,它确实产生了正确的答案。谢谢,这看起来更干净了。不过,速度似乎没有加快。关于降低速度有什么想法吗?我只做了一个for循环。我在两个循环中都实现了它,现在速度快了20倍。我非常感谢您的帮助和您的相关资源。你是这个社区的重要组成部分@GregorFreund-查看我的上一次编辑,100x100快了200倍。谢谢,这是非常有用的信息。只有一个问题:例如IM[iP,:]和IM[iP]之间有什么区别?它仅仅是为了可读性吗?