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

查看:36
本文介绍了使用 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 写了那个解释,这是为一堆编写 np.meshgrid 的快捷方式aranges.)

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天全站免登陆