使用Python按列插值2D矩阵

时间:2018-01-20 13:17:08

标签: python numpy matrix interpolation

我正在尝试将尺寸为(5,3)的2D numpy矩阵插入到沿着轴1(列)的尺寸(7,3)的矩阵中。显然,错误的方法是在原始矩阵之间的任意位置随机插入行,请参阅以下示例:

Source:
 [[0, 1, 1]
  [0, 2, 0]
  [0, 3, 1]
  [0, 4, 0]
  [0, 5, 1]]

Target (terrible interpolation -> not wanted!):
 [[0, 1, 1]
  [0, 1.5, 0.5]
  [0, 2, 0]
  [0, 3, 1]
  [0, 3.5, 0.5]
  [0, 4, 0]
  [0, 5, 1]]

正确的方法是将每一行考虑在内并在所有行之间插值以将源矩阵扩展为(7,3)矩阵。我知道scipy.interpolate.interp1d或scipy.interpolate.interp2d方法,但无法使其与其他Stack Overflow帖子或网站一起使用。我希望收到任何类型的提示或技巧。

更新#1:预期值应该等间隔。

更新#2: 我想要做的是基本上使用原始矩阵的单独列,将列的长度扩展为7并在原始列的值之间进行插值。请参阅以下示例:

Source:
 [[0, 1, 1]
  [0, 2, 0]
  [0, 3, 1]
  [0, 4, 0]
  [0, 5, 1]]

Split into 3 separate Columns:
 [0    [1    [1
  0     2     0
  0     3     1
  0     4     0
  0]    5]    1] 

Expand length to 7 and interpolate between them, example for second column:
 [1
  1.66
  2.33
  3
  3.66
  4.33
  5]   

2 个答案:

答案 0 :(得分:3)

似乎每个列都可以完全独立地处理,但是对于每个列,您需要基本上定义一个“x”坐标,以便您可以使用一些函数“f(x)”来生成输出矩阵。 除非矩阵中的行与某些其他数据结构相关联(例如时间戳矢量),否则一组明显的x值就是行号:

fit = scipy.interpolate.interp1d(x, Source, axis=0)

然后,您可以构建插值函数:

Target = fit(numpy.linspace(0, Source.shape[0]-1, 7)

并使用它来构建输出矩阵:

array([[ 0.        ,  1.        ,  1.        ],
       [ 0.        ,  1.66666667,  0.33333333],
       [ 0.        ,  2.33333333,  0.33333333],
       [ 0.        ,  3.        ,  1.        ],
       [ 0.        ,  3.66666667,  0.33333333],
       [ 0.        ,  4.33333333,  0.33333333],
       [ 0.        ,  5.        ,  1.        ]])

产生:

user@[ip]

默认情况下,scipy.interpolate.interp1d使用分段线性插值。 scipy.interpolate中有更多的奇异选项,基于更高阶的多项式等。插值本身就是一个很大的主题,除非矩阵的行具有某些特定的属性(例如,带有一个特定属性的信号的常规样本)已知的频率范围),可能没有“真正正确”的插值方式。因此,在某种程度上,插值方案的选择会有些随意。

答案 1 :(得分:1)

您可以按照以下方式执行此操作:

from scipy.interpolate import interp1d
import numpy as np


a = np.array([[0, 1, 1],
               [0, 2, 0],
               [0, 3, 1],
               [0, 4, 0],
               [0, 5, 1]])

x = np.array(range(a.shape[0]))

# define new x range, we need 7 equally spaced values
xnew = np.linspace(x.min(), x.max(), 7)

# apply the interpolation to each column
f = interp1d(x, a, axis=0)

# get final result
print(f(xnew))

这将打印

[[ 0.          1.          1.        ]
 [ 0.          1.66666667  0.33333333]
 [ 0.          2.33333333  0.33333333]
 [ 0.          3.          1.        ]
 [ 0.          3.66666667  0.33333333]
 [ 0.          4.33333333  0.33333333]
 [ 0.          5.          1.        ]]