简体   繁体   English

使用Python沿列插值2D矩阵

[英]Interpolate 2D matrix along columns using Python

I am trying to interpolate a 2D numpy matrix with the dimensions (5, 3) to a matrix with the dimensions (7, 3) along the axis 1 (columns). 我正在尝试将尺寸为(5,3)的2D numpy矩阵插值为沿轴1(列)的尺寸为(7,3)的矩阵。 Obviously, the wrong approach would be to randomly insert rows anywhere between the original matrix, see the following example: 显然,错误的方法是在原始矩阵之间的任意位置随机插入行,请参见以下示例:

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]]

The correct approach would be to take every row into account and interpolate between all of them to expand the source matrix to a (7, 3) matrix. 正确的方法是考虑到每一行并在所有行之间进行插值,以将源矩阵扩展为(7,3)矩阵。 I am aware of the scipy.interpolate.interp1d or scipy.interpolate.interp2d methods, but could not get it to work with other Stack Overflow posts or websites. 我知道scipy.interpolate.interp1d或scipy.interpolate.interp2d方法,但无法使其与其他Stack Overflow帖子或网站一起使用。 I hope to receive any type of tips or tricks. 我希望收到任何类型的提示或技巧。

Update #1: The expected values should be equally spaced. 更新#1:期望值应均匀分布。

Update #2: What I want to do is basically use the separate columns of the original matrix, expand the length of the column to 7 and interpolate between the values of the original column. 更新#2:我要做的基本上是使用原始矩阵的单独列,将列的长度扩展为7,然后在原始列的值之间进行插值。 See the following example: 请参见以下示例:

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]   

It seems like each column can be treated completely independently, but for each column you need to define essentially an "x" coordinate so that you can fit some function "f(x)" from which you generate your output matrix. 似乎可以完全独立地对待每一列,但是对于每一列,您基本上都需要定义一个“ x”坐标,以便可以拟合一些函数“ f(x)”,从中生成输出矩阵。 Unless the rows in your matrix are associated with some other datastructure (eg a vector of timestamps), an obvious set of x values is just the row-number: 除非矩阵中的行与其他数据结构(例如,时间戳记的向量)相关联,否则x值的明显集合就是行号:

x = numpy.arange(0, Source.shape[0])

You can then construct an interpolating function: 然后可以构造一个插值函数:

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

and use that to construct your output matrix: 并使用它来构建输出矩阵:

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

which produces: 产生:

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.        ]])

By default, scipy.interpolate.interp1d uses piecewise-linear interpolation. 默认情况下,scipy.interpolate.interp1d使用分段线性插值。 There are many more exotic options within scipy.interpolate , based on higher order polynomials, etc. Interpolation is a big topic in itself, and unless the rows of your matrix have some particular properties (eg being regular samples of a signal with a known frequency range), there may be no "truly correct" way of interpolating. scipy.interpolate中 ,还有基于高阶多项式等的更多奇特选项。插值本身就是一个大话题,并且除非矩阵的行具有某些特定属性(例如,具有已知频率的信号的常规样本)范围),可能没有“真正正确”的插值方式。 So, to some extent, the choice of interpolation scheme will be somewhat arbitrary. 因此,在某种程度上,插值方案的选择会有些随意。

You can do this as follows: 您可以按照以下步骤进行操作:

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))

This will print 这将打印

[[ 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.        ]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM