使用scipy.interpolate.interpn插值N维数组 [英] Using scipy.interpolate.interpn to interpolate a N-Dimensional array

查看:1552
本文介绍了使用scipy.interpolate.interpn插值N维数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的数据取决于4个变量:a,b,c和d.我想插值返回一个二维数组,该数组对应于a和b的单个值,以及c和d的值数组.但是,数组大小不必相同.具体来说,我的数据来自晶体管仿真.电流取决于此处的4个变量.我想绘制一个参数变化.参数上的点数比水平轴的点数少得多.

Suppose I have data that depends on 4 variables: a, b, c and d. I want interpolate to return a 2D array which corresponds to a single value of a and b, and an array of values for c and d. However, The array size need not be the same. To be specific, my data comes from a transistor simulation. The current depends on 4 variables here. I want to plot a parametric variation. The number of points on the parameter is a lot less than the number of points for the horizontal axis.

import numpy as np
from scipy.interpolate import interpn
arr = np.random.random((4,4,4,4))
x1 = np.array([0, 1, 2, 3])
x2 = np.array([0, 10, 20, 30])
x3 = np.array([0, 10, 20, 30])
x4 = np.array([0, .1, .2, .30])
points = (x1, x2, x3, x4)

以下作品:

xi = (0.1, 9, np.transpose(np.linspace(0, 30, 4)), np.linspace(0, 0.3, 4))
result = interpn(points, arr, xi)

这也是如此:

xi = (0.1, 9, 24, np.linspace(0, 0.3, 4))
result = interpn(points, arr, xi)

但不是这样:

xi = (0.1, 9, np.transpose(np.linspace(0, 30, 3)), np.linspace(0, 0.3, 4))
result = interpn(points, arr, xi)

如您所见,在最后一种情况下,

xi中最后两个数组的大小是不同的. scipy不支持这种功能吗?或者我不正确地使用interpn吗?我需要创建一个图,其中xi的一个是参数,而另一个是水平轴.

As you can see, in the last case, the size of the last two arrays in xi is different. Is this kind of functionality not supported by scipy or am I using interpn incorrectly? I need this create a plot where one of the xi's is a parameter while the other is the horizontal axis.

推荐答案

我将尝试以2D方式向您解释,以便您更好地了解正在发生的事情.首先,让我们创建一个线性数组进行测试.

I'll try to explain this to you in 2D so that you get a better idea of what's happening. First, let's create a linear array to test with.

import numpy as np

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

# Set up grid and array of values
x1 = np.arange(10)
x2 = np.arange(10)
arr = x1 + x2[:, np.newaxis]

# Set up grid for plotting
X, Y = np.meshgrid(x1, x2)

# Plot the values as a surface plot to depict
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, arr, rstride=1, cstride=1, cmap=cm.jet,
                       linewidth=0, alpha=0.8)
fig.colorbar(surf, shrink=0.5, aspect=5)

这给我们:

然后,假设您要沿一条线进行插值,即沿第一维插入一个点,但沿第二维插入所有点.这些点显然不在原始数组(x1, x2)中.假设我们要插入到点x1 = 3.5,该点位于x1轴上的两个点之间.

Then, let's say you want to interpolate along a line, i.e., one point along the first dimension, but all points along the second dimension. These points are not in the original arrays (x1, x2) obviously. Suppose we want to interpolate to a point x1 = 3.5, which is in between two points on the x1-axis.

from scipy.interpolate import interpn

interp_x = 3.5           # Only one value on the x1-axis
interp_y = np.arange(10) # A range of values on the x2-axis

# Note the following two lines that are used to set up the
# interpolation points as a 10x2 array!
interp_mesh = np.array(np.meshgrid(interp_x, interp_y))
interp_points = np.rollaxis(interp_mesh, 0, 3).reshape((10, 2))

# Perform the interpolation
interp_arr = interpn((x1, x2), arr, interp_points)

# Plot the result
ax.scatter(interp_x * np.ones(interp_y.shape), interp_y, interp_arr, s=20,
           c='k', depthshade=False)
plt.xlabel('x1')
plt.ylabel('x2')

plt.show()

这将为您提供所需的结果:请注意,黑点正确位于平面上,x1值为3.5.

This gives you the result as desired: note that the black points correctly lie on the plane, at an x1 value of 3.5.

请注意,大多数魔术"以及您问题的答案都位于这两行:

Note that most of the "magic", and the answer to your question, lies in these two lines:

interp_mesh = np.array(np.meshgrid(interp_x, interp_y))
interp_points = np.rollaxis(interp_mesh, 0, 3).reshape((10, 2))

我已经解释了其他地方的工作方式.简而言之,它要做的是创建一个大小为10x2的数组,其中包含要在其上插入arr的10个点的坐标. (那篇文章和这篇文章之间的唯一区别是,我已经为np.mgrid编写了说明,这是为一堆arange编写np.meshgrid的快捷方式.)

I have explained the working of this elsewhere. In short, what it does is to create an array of size 10x2, containing the coordinates of the 10 points you want to interpolate arr at. (The only difference between that post and this one is that I've written that explanation for np.mgrid, which is a shortcut to writing np.meshgrid for a bunch of aranges.)

对于4x4x4x4的保护套,您可能需要这样的东西:

For your 4x4x4x4 case, you will probably need something like this:

interp_mesh = np.meshgrid([0.1], [9], np.linspace(0, 30, 3),
                          np.linspace(0, 0.3, 4))
interp_points = np.rollaxis(interp_mesh, 0, 5)
interp_points = interp_points.reshape((interp_mesh.size // 4, 4))
result = interpn(points, arr, interp_points)

希望有帮助!

这篇关于使用scipy.interpolate.interpn插值N维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆