将数组插值到恒定密度

时间:2018-12-07 14:26:36

标签: python numpy interpolation

我一直在讨论这个看似简单的问题已经好几个小时了,但我似乎找不到答案。

设置非常简单:给定一个浮点数组,对额外的点进行插值,以便以恒定(或近似恒定)的密度分布结果插值数据。

标准插值有效,但是插值点的密度根本不是恒定的(右图):

enter image description here

我肯定在这里缺少明显的东西,因为我确信这个问题并不那么复杂,而且我已经苦苦挣扎了很长时间。

非常感谢您的帮助。


import numpy as np
import matplotlib.pyplot as plt

data = np.array([13.826, 13.608, 13.163, 13.034, 12.672, 12.126, 11.585, 11.192,
       10.609, 10.082,  9.67 ,  9.261,  9.175,  8.869,  8.408,  7.868,
        7.317,  6.827,  6.52 ,  6.375,  5.968,  5.601,  5.271,  5.242,
        4.961,  4.888,  4.661,  4.395,  4.376,  4.286,  4.105,  4.019,
        3.845,  3.785,  3.601,  3.371,  3.226,  3.156,  2.984,  2.96 ,
        2.931,  2.786,  2.757,  2.62 ,  2.554,  2.473,  2.464,  2.451,
        2.309,  2.196,  2.15 ,  2.061,  1.987,  1.907,  1.825,  1.803,
        1.721,  1.62 ,  1.595,  1.57 ,  1.462,  1.346,  1.334,  1.208,
        1.09 ,  1.033,  0.94 ,  0.874,  0.852,  0.857,  0.872,  0.884,
        0.889,  0.888,  0.9  ,  0.856,  0.756,  0.652,  0.567,  0.495,
        0.432,  0.378,  0.331,  0.293,  0.264,  0.244,  0.232,  0.228,
        0.228,  0.231,  0.239,  0.248,  0.261,  0.278,  0.308,  0.357,
        0.417,  0.495,  0.575,  0.59 ,  0.544,  0.465,  0.355,  0.246,
        0.138,  0.032, -0.032, -0.075, -0.139, -0.179, -0.28 , -0.38 ,
       -0.471, -0.565, -0.671, -0.772, -0.872, -0.974, -1.069, -1.164,
       -1.257, -1.169, -1.131, -1.084, -1.016, -0.936, -0.846, -0.748,
       -0.647, -0.546, -0.444, -0.348, -0.274, -0.159, -0.05 ,  0.091,
        0.145,  0.236,  0.318,  0.239,  0.105, -0.036, -0.168, -0.303,
       -0.304, -0.429, -0.571, -0.685, -0.704, -0.806, -0.849, -0.865,
       -0.835, -0.823, -0.892, -0.928, -0.978, -1.077, -1.156, -1.065,
       -1.153, -1.244, -1.332, -1.426, -1.523, -1.623, -1.722, -1.819,
       -1.918, -2.03 , -2.135, -2.233, -2.33 , -2.423, -2.516, -2.609,
       -2.7  , -2.791, -2.88 , -2.948, -3.913])

# Number of points to interpolate
N = 1000
t = np.linspace(0, 1, N)
xp = np.linspace(0, 1, data.size)
# Interpolated data
d_interp = np.interp(t, xp, data)

plt.subplot(121)
plt.scatter(t, d_interp, label='Interpolated points')
plt.scatter(xp, data, s=4, label='Original data')
plt.legend()
plt.subplot(122)
plt.hist(d_interp, 25, label='Density of interpolated data')
plt.legend()
plt.show()

1 个答案:

答案 0 :(得分:0)

您要采样y点而不是x点。采样y点很容易:

d_interp = np.linspace(data.min(), data.max(), N)

现在您要插值(y,x)而不是(x,y)。您可以尝试使用此方法,但这不起作用:

t = np.interp(d_interp, data, xp)

问题在于对相应的x点进行插值:np.interp期望您的x单调增加。实际上,通过在图表中选择随机的y点(例如x=0),您可以获得2或3个对应的x点。因此,对于每个y,您都不知道要选择什么x

我建议的解决方案是,鉴于您的功能大部分在减少,请使用蒙版过滤样本集:

mask = np.append(True, np.diff(data) < 0)   #first points, plus all monotonally decreasing y points
d_interp = np.linspace(data.min(), data.max(), N)
t = np.interp(d_interp, data[mask][::-1], xp[mask][::-1])

output