【问题标题】:Extrapolate 2d numpy array in one dimension一维外推 2d numpy 数组
【发布时间】:2016-09-14 14:37:29
【问题描述】:

我有来自模拟的 numpy.array 数据集,但我错过了边缘的点 (x=0.1),如何将 z 中的数据内插/外推到边缘?我有:

x = [ 0.  0.00667  0.02692  0.05385  0.08077]
y = [ 0.     10.     20.     30.     40.     50.]

#       0.      0.00667 0.02692 0.05385 0.08077 
z = [[ 25.     25.     25.     25.     25.   ]   # 0.
     [ 25.301  25.368  25.617  26.089  26.787]   # 10.
     [ 25.955  26.094  26.601  27.531  28.861]   # 20.
     [ 26.915  27.126  27.887  29.241  31.113]   # 30.
     [ 28.106  28.386  29.378  31.097  33.402]   # 40.
     [ 29.443  29.784  30.973  32.982  35.603]]  # 50.

我想在 z 中添加一个对应于 x = 0.1 的新列,以便我的新 x 将是

x_new = [ 0.  0.00667  0.02692  0.05385  0.08077  0.1]

#       0.      0.00667 0.02692 0.05385 0.08077 0.01
z = [[ 25.     25.     25.     25.     25.       ?   ]   # 0.
     [ 25.301  25.368  25.617  26.089  26.787    ?   ]   # 10.
     [ 25.955  26.094  26.601  27.531  28.861    ?   ]   # 20.
     [ 26.915  27.126  27.887  29.241  31.113    ?   ]   # 30.
     [ 28.106  28.386  29.378  31.097  33.402    ?   ]   # 40.
     [ 29.443  29.784  30.973  32.982  35.603    ?   ]]  # 50.

所有的“?”替换为内插/外推数据。 感谢您的帮助!

【问题讨论】:

  • 外推值取决于序列中渐进元素的关系是线性的还是对数的。如果是前者,你可以将倒数第二列乘以你的常数,如果是后者,那么你必须查看列之间的进展并确定一个合适的值。此外,这绝对是外推。

标签: python arrays numpy interpolation extrapolation


【解决方案1】:

你看过 scipy.interpolate2d.interp2d(它使用样条线)吗?

from scipy.interpolate import interp2d
fspline = interp2d(x,y,z) # maybe need to switch x and y around
znew = fspline([0.1], y)
z = np.c_[[z, znew] # to join arrays

编辑

@dnalow 和我设想的方法大致如下:

import numpy as np
import matplotlib.pyplot as plt

# make some test data
def func(x, y):
    return np.sin(np.pi*x) + np.sin(np.pi*y)

xx, yy = np.mgrid[0:2:20j, 0:2:20j]
zz = func(xx[:], yy[:]).reshape(xx.shape)

fig, (ax1, ax2, ax3, ax4) = plt.subplots(1,4, figsize=(13, 3))
ax1.imshow(zz, interpolation='nearest')
ax1.set_title('Original')

# remove last column
zz[:,-1] = np.nan
ax2.imshow(zz, interpolation='nearest')
ax2.set_title('Missing data')

# compute missing column using simplest imaginable model: first order Taylor
gxx, gyy = np.gradient(zz[:, :-1])
zz[:, -1] =  zz[:, -2] + gxx[:, -1] + gyy[:,-1]
ax3.imshow(zz, interpolation='nearest')
ax3.set_title('1st order Taylor approx')

# add curvature to estimate
ggxx, _ = np.gradient(gxx)
_, ggyy = np.gradient(gyy)
zz[:, -1] = zz[:, -2] + gxx[:, -1] + gyy[:,-1] + ggxx[:,-1] + ggyy[:, -1]
ax4.imshow(zz, interpolation='nearest')
ax4.set_title('2nd order Taylor approx')

fig.tight_layout()
fig.savefig('extrapolate_2d.png')

plt.show()

您可以通过
来改进估算值 (a) 添加高阶导数(又名泰勒展开),或
(b) 计算比 x 和 y 更多​​方向的梯度(然后相应地对梯度进行加权)。

此外,如果您预先平滑图像,您将获得更好的渐变(现在我们有一个完整的 Sobel 过滤器......)。

【讨论】:

  • 我尝试了您的建议,但发生的情况是它只获取每行中的最后一个值并将其复制到另一列中,可能是因为我尝试超出原始数据并且 interp2d 仅在值之间起作用?
  • 由于这是外推,插值无济于事。当然不是interp2d。此外,仅当存在可以推断数据的模型时,推断才有意义。如果不是,则不清楚如何获得最佳值。因此,这不仅仅是一个数字问题。
  • 是的,应该记住 interp2d 在边缘(或 nan)处计算为最接近的值。我认为@dnalow 是对的:您需要计算一些局部梯度,甚至可能是曲率并建立一个明确的模型。
  • 原则上,如果什么都不知道,最接近的值其实是最可靠的。因此,我认为答案值得+1。假设函数有一些“不错”的行为,可以使用多项式近似来继续数据,类似于泰勒展开:stackoverflow.com/questions/33964913/…stackoverflow.com/questions/7997152/…
  • 感谢 Paul 的精彩解释!这正是我需要的(除了这个特殊情况的一个维度)。并感谢您提供有趣的 cmets,我会记住这一点!幸运的是,这些数据代表了一种具有“平滑”梯度的物理现象,所以我相信 Paul 的解决方案在这种情况下对我有用。
猜你喜欢
  • 2020-11-05
  • 2021-05-15
  • 1970-01-01
  • 2022-07-08
  • 2021-12-24
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2017-05-19
相关资源
最近更新 更多