插值2个numpy数组

时间:2016-10-06 00:33:08

标签: python numpy

是否有任何numpy或scipy或python函数在两个2D numpy数组之间进行插值?我有两个2D numpy数组,我想对第一个numpy数组应用更改,使其类似于第二个2D数组。约束是我希望更改顺利。例如,让数组为:

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

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

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

2 个答案:

答案 0 :(得分:2)

您刚刚描述了卡尔曼滤波/数据融合问题。你有一个初始状态 A 有一些错误,你有一些观察 B 也有一些噪音。您希望通过从 B 中注入一些信息来改善对状态 A 的估计,同时考虑两个数据集中的空间相关错误。我们没有关于 A B 中的错误的任何先前信息,因此我们可以进行弥补。这是一个实现:

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)

现在,此方法仅在您的数据无偏见时才有效。所以意味着(A)必须等于平均值​​(B)。但无论如何,你仍然会得到好的结果。此外,您可以随心所欲地使用协方差矩阵。我建议您阅读卡尔曼滤镜维基百科页面了解更多详情。

顺便说一下,上面的例子产生了:

[[ 27.92920141  90.65490699   7.17920141]
 [ 55.92920141   7.65490699  79.17920141]
 [ 10.92920141  24.65490699  52.17920141]]

答案 1 :(得分: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