Поскольку интерполяция равна 1d с изменением значений y
, она должна выполняться для каждого 1d среза t. Вероятно, это быстрее, чем l oop явно, но точнее, чем l oop, используя np.apply_along_axis
import numpy as np
t = np.arange( 18 ).reshape(3,3,2)
x = np.linspace( 0, t.shape[0]-1, 4)
xp = np.arange(t.shape[0])
def interfunc( arr ):
""" Function interpolates a 1d array. """
return np.interp( x, xp, arr )
np.apply_along_axis( interfunc, 0, t ) # apply function along axis 0
""" Result
array([[[ 0., 1.],
[ 2., 3.],
[ 4., 5.]],
[[ 4., 5.],
[ 6., 7.],
[ 8., 9.]],
[[ 8., 9.],
[10., 11.],
[12., 13.]],
[[12., 13.],
[14., 15.],
[16., 17.]]]) """
С явными циклами
result = np.zeros((4,3,2))
for c in range(t.shape[1]):
for p in range(t.shape[2]):
result[:,c,p] = np.interp( x, xp, t[:,c,p])
На моей машине второй вариант работает пополам время.
Изменить для использования np.nditer
Поскольку результат и параметр имеют разные формы, мне кажется, что мне нужно создать два объекта np.nditer, один для параметр и один для результата. Это моя первая попытка использовать nditer
для чего-либо, чтобы это могло быть слишком сложным.
def test( t ):
ts = t.shape
result = np.zeros((ts[0]+1,ts[1],ts[2]))
param = np.nditer( [t], ['external_loop'], ['readonly'], order = 'F')
with np.nditer( [result], ['external_loop'], ['writeonly'], order = 'F') as res:
for p, r in zip( param, res ):
r[:] = interfunc(p)
return result
Это немного медленнее, чем явные циклы, и менее легко следовать, чем любое из других решений.