是否有任何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循环。
答案 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
。