插值2个numpy数组

4

是否有任何numpy、scipy或python函数可以在两个2D numpy数组之间进行插值?我有两个2D numpy数组,我想对第一个数组应用更改,使其类似于第二个2D数组。约束条件是我希望更改是平滑的。例如,假设数组如下:

A
[[1 1 1
  1 1 1
  1 1 1]]

并且

B
[[34  100 15
  62  17  87
  17  34  60]]

为了使A类似于B,我可以将33添加到A的第一个网格单元,依此类推。然而,为了使更改更加平滑,我计划在数组B上使用2x2窗口计算平均值,然后将结果应用于数组A。是否有内置的numpy或scipy方法可以执行此操作或遵循此方法而不使用for循环?

1
你能更清楚地解释一下“计算平均值”和“将结果应用于数组A”的意思吗? - Praveen
1
另外,“使A类似于B”确切地是什么意思?你能加上你想要避免的循环吗?这将极大地帮助确定你想要产生的结果。 - Arcturus B
甚至只需添加所得矩阵,以便我们了解您在此情况下想要的期望结果。 - Brian
2个回答

2
您刚刚描述了一个卡尔曼滤波/数据融合问题。您有一个初始状态A,其中存在一些误差,并且您还有一些观测值B,这些观测值也存在一些噪声。您希望通过注入来自B的信息来改进对状态A的估计,同时考虑两个数据集中空间相关的错误。我们没有关于AB中的错误的先前信息,因此可以随意制定。以下是一个实现示例:
import numpy as np

# Make a matrix of the distances between points in an array
def dist(M):
    nx = M.shape[0]
    ny = M.shape[1]
    x = np.ravel(np.tile(np.arange(nx),(ny,1))).reshape((nx*ny,1))
    y = np.ravel(np.tile(np.arange(ny),(nx,1))).reshape((nx*ny,1))
    n,m = np.meshgrid(x,y)
    d = np.sqrt((n-n.T)**2+(m-m.T)**2)
    return d

# Turn a distance matrix into a covariance matrix. Here is a linear covariance matrix.
def covariance(d,scaling_factor):
    c = (-d/np.amax(d) + 1)*scaling_factor
    return c

A = np.array([[1,1,1],[1,1,1],[1,1,1]]) # background state
B = np.array([[34,100,15],[62,17,87],[17,34,60]]) # observations

x = np.ravel(A).reshape((9,1)) # vector representation
y = np.ravel(B).reshape((9,1)) # vector representation

P_a = np.eye(9)*50 # background error covariance matrix (set to diagonal here)
P_b = covariance(dist(B),2) # observation error covariance matrix (set to a function of distance here)

# Compute the Kalman gain matrix
K = P_a.dot(np.linalg.inv(P_a+P_b))

x_new = x + K.dot(y-x)
A_new = x_new.reshape(A.shape)

print(A)
print(B)
print(A_new)

现在,这种方法只适用于您的数据是无偏的情况。因此,mean(A)必须等于mean(B)。但是,即使如此,您仍然会得到可以接受的结果。此外,您可以随意处理协方差矩阵。我建议阅读Kalman滤波器维基百科页面以获取更多详细信息。
顺便说一句,上面的示例产生了:
[[ 27.92920141  90.65490699   7.17920141]
 [ 55.92920141   7.65490699  79.17920141]
 [ 10.92920141  24.65490699  52.17920141]]

1

平滑的一种方法是使用convolve2d

import numpy as np
from scipy import signal

B = np.array([[34, 100, 15],
              [62,  17, 87],
              [17,  34, 60]])
kernel = np.full((2, 2), .25)
smoothed = signal.convolve2d(B, kernel)
# [[  8.5   33.5   28.75   3.75]
#  [ 24.    53.25  54.75  25.5 ]
#  [ 19.75  32.5   49.5   36.75]
#  [  4.25  12.75  23.5   15.  ]]

上述方法在矩阵的四周填充零后,计算每个2x2窗口的平均值,并将该值放置在窗口中心。
如果矩阵实际上更大,则使用3x3内核(例如np.full((3, 3), 1/9))并将mode ='same'传递给convolve2d会产生平滑的B,其形状保持不变,并且元素与原始元素“匹配”。否则,您可能需要决定如何处理边界值,以使形状再次相同。
为了将A移向平滑的B,可以使用标准算术运算将其设置为所选矩阵的仿射组合,例如:A = .2 * A + .8 * smoothed

1
不使用数组A。 - JARS
@JARS 在平滑处理完 B 后,您可以计算 AB 的一些仿射组合,例如:.2 * A + .8 * B。为了使 AB 的形状匹配,请将 mode=same 传递给 convolve2d(并可能使用奇数大小的卷积核,如3x3)。 - wrwrwr
通过精心选择内核,您可以实现许多不同类型的平滑处理,其中一个常见的例子是来自图像处理领域的高斯模糊。 - wrwrwr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接