在二维数组上使用插值函数

1 投票
3 回答
1335 浏览
提问于 2025-04-17 17:36

我有一个一维的函数,它在处理一个很大的二维数组的'x'值时需要花费很多时间。所以我觉得用SciPy的插值功能来创建一个插值函数,然后用这个函数来计算'y'值会快很多。不过,我发现插值函数不能用在超过一维的数组上。

举个例子:

# First, I create the interpolation function in the domain I want to work
x = np.arange(1, 100, 0.1)
f = exp(x) # a complicated function
f_int = sp.interpolate.InterpolatedUnivariateSpline(x, f, k=2)

# Now, in the code I do that
x = [[13, ..., 1], [99, ..., 45], [33, ..., 98] ..., [15, ..., 65]]
y = f_int(x)
# Which I want that it returns y = [[f_int(13), ..., f_int(1)], ..., [f_int(15), ..., f_int(65)]]

但是返回的是:

ValueError: object too deep for desired array

我知道我可以对所有的'x'值进行循环处理,但我不确定这样做是否更好……

谢谢!

补充:

这样一个函数也能完成这个任务:

def vector_op(function, values):

    orig_shape = values.shape
    values = np.reshape(values, values.size)

    return np.reshape(function(values), orig_shape)

我试过np.vectorize,但它太慢了……

3 个回答

0

我会用一种叫做 列表推导式map 的组合(可能还有其他方法,比如用两个嵌套的 map,但我可能没想到)

In [24]: x
Out[24]: [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

In [25]: [map(lambda a: a*0.1, x_val) for x_val in x]
Out[25]: 
[[0.1, 0.2, 0.30000000000000004],
 [0.1, 0.2, 0.30000000000000004],
 [0.1, 0.2, 0.30000000000000004]]

这只是为了举个例子……把 lambda a: a*0.1 替换成你的函数 f_int

1

我想你是想在numpy中使用向量化函数:

#create some random test data
test = numpy.random.random((100,100))

#a normal python function that you want to apply
def myFunc(i):
    return np.exp(i)

#now vectorize the function so that it will work on numpy arrays
myVecFunc = np.vectorize(myFunc)

result = myVecFunc(test)
2

如果 f_int 需要一维的数据,你就得把输入的数据变成一维,然后把它给插值器,最后再把它变回原来的形状:

>>> x = np.arange(1, 100, 0.1)
>>> f = 2 * x # a simple function to see the results are good
>>> f_int = scipy.interpolate.InterpolatedUnivariateSpline(x, f, k=2)

>>> x = np.arange(25).reshape(5, 5) + 1
>>> x
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])
>>> x_int = f_int(x.reshape(-1)).reshape(x.shape)
>>> x_int
array([[  2.,   4.,   6.,   8.,  10.],
       [ 12.,  14.,  16.,  18.,  20.],
       [ 22.,  24.,  26.,  28.,  30.],
       [ 32.,  34.,  36.,  38.,  40.],
       [ 42.,  44.,  46.,  48.,  50.]])

x.reshape(-1) 是用来把数据变成一维的,而 .reshape(x.shape) 则是把它恢复到原来的样子。

撰写回答