使用numpy进行平滑线性插值

wbrvyc0a  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(171)

bounty将在11小时后到期。此问题的答案有资格获得+50声望奖励。carlitador正在寻找来自可靠来源的**答案 *:

这是我想解决的一个重要问题
我需要重新编码一个等价的numpy interp函数。为了做到这一点,我想建立一个成对距离矩阵,然后使用这个矩阵来定义“权重”,我用它来乘以目标值。

def interp_diff(x, xp, fp):
    dxp = np.diff(xp)
    dxp = np.concatenate(([dxp[0]], dxp))  

    pairwise_distance = np.abs(x[:, np.newaxis] - xp)  # Calculate the absolute differences between x and xp

    # Add a small epsilon to pairwise distances to avoid division by zero
    epsilon = 1e-8
    pairwise_distance += epsilon

    weights = 1 / pairwise_distance  # Calculate the weights based on the differences

    # Normalize the weights
    weights /= np.sum(weights, axis=1)[:, np.newaxis]

    # Apply hardness threshold to the weights
    weights = np.where(weights > 0, weights, 0)

    return np.dot(weights, fp)

当xp值放置在规则栅格上时,此操作会产生预期结果,但如果xp值的间距不均匀,则此操作不起作用。有没有人有一个想法,使这一工作的任何间距xp?我的限制是我不能使用索引相关的方法(argsort,argwhere,searchsorted等...)。这就是为什么它有点挑战性
常规网格上的用法示例:

x_np = np.linspace(0,5,4)
y_np = np.sin(x_np)
x_i = x_np
x_i = np.linspace(0,5,10)
y_i = interp_diff(x_i,xp=x_np,fp=y_np)
ax = plt.figure().gca()
ax.scatter(x_np,y_np)
ax.scatter(x_i,y_i,marker='+',s=30,alpha=0.7)
ax.plot(x_i,y_i)
plt.show()

产生预期结果:

但是,切换到非均匀间隔网格:

def sinspace(start,stop,num):

    ones = 0 * start + 1
    return start + (stop - start) * (1 - np.cos(np.linspace(
        0 * ones,
        np.pi / 2 * ones,
        num
    )))
x_np = sinspace(0,5,4)
y_np = np.sin(x_np)
x_i = x_np
x_i = np.linspace(0,5,10)
y_i = interp_diff(x_i,xp=x_np,fp=y_np)
ax = plt.figure().gca()
ax.scatter(x_np,y_np)
ax.scatter(x_i,y_i,marker='+',s=30,alpha=0.7)
ax.plot(x_i,y_i)
plt.show()

这就是我得到的

谢谢

r6hnlfcb

r6hnlfcb1#

我无法用你提供的代码的稍微修改版本复制你的结果:

import numpy
from matplotlib import pyplot

def interp_diff(x, xp, fp):
    dxp = numpy.diff(xp)
    dxp = numpy.concatenate(([dxp[0]], dxp))

    pairwise_distance = numpy.abs(x[:, numpy.newaxis] - xp)  # Calculate the absolute differences between x and xp

    # Add a small epsilon to pairwise distances to avoid division by zero
    epsilon = 1e-8
    pairwise_distance += epsilon

    weights = 1 / pairwise_distance  # Calculate the weights based on the differences

    # Normalize the weights
    weights /= numpy.sum(weights, axis=1)[:, numpy.newaxis]

    # Apply hardness threshold to the weights
    weights = numpy.where(weights > 0, weights, 0)

    return numpy.dot(weights, fp)

# 1 : 1 grid
x_np = numpy.linspace(0,5,4)
y_np = numpy.sin(x_np)
x_i = x_np
y_i = interp_diff(x_i,xp=x_np,fp=y_np)
ax = pyplot.figure().gca()
ax.scatter(x_np,y_np)
ax.scatter(x_i,y_i,marker='+',s=30,alpha=0.7)
ax.plot(x_i,y_i)
pyplot.show()

# 1 : 2.5 grid
x_np = numpy.linspace(0,5,4)
y_np = numpy.sin(x_np)
x_i = numpy.linspace(0,5,10)
y_i = interp_diff(x_i,xp=x_np,fp=y_np)
ax = pyplot.figure().gca()
ax.scatter(x_np,y_np)
ax.scatter(x_i,y_i,marker='+',s=30,alpha=0.7)
ax.plot(x_i,y_i)
pyplot.show()

您使用的是哪个版本的numpymatplotlib库?

相关问题