Python 避免循环,在三维numpy阵列的尺寸上插值

Python 避免循环,在三维numpy阵列的尺寸上插值,python,arrays,loops,numpy,3d,Python,Arrays,Loops,Numpy,3d,我有一个尺寸为l、n、m的大型3D numpy数组,其中的元素分别对应于尺寸为l、n和m的x、y和z的一维数组。我想通过在x和y的每个组合的z值之间插值,找到给定值a和长度b的元素。这将给出尺寸为l、n、b的输出3D数组。我希望完全使用numpy数组来实现这一点,而不是求助于for循环 例如,如果我的3D阵列的尺寸为2,3,4: x = 1 | z = 1 | 2 | 3 | 4 - - - - - - - - - - - - - - y = 1 |[[[ 0, 1, 2, 3],

我有一个尺寸为l、n、m的大型3D numpy数组,其中的元素分别对应于尺寸为l、n和m的x、y和z的一维数组。我想通过在x和y的每个组合的z值之间插值,找到给定值a和长度b的元素。这将给出尺寸为l、n、b的输出3D数组。我希望完全使用numpy数组来实现这一点,而不是求助于for循环

例如,如果我的3D阵列的尺寸为2,3,4:

x = 1 | z = 1 | 2 | 3 | 4 
- - - - - - - - - - - - - - 
y = 1 |[[[ 0,  1,  2,  3],       
y = 2 |  [ 4,  5,  6,  7],
y = 3 |  [ 8,  9, 10, 11]],

x = 2 | z = 1 | 2 | 3 | 4 
- - - - - - - - - - - - -
y = 1 | [[ 12, 13, 14, 15],        
y = 2 |  [ 16, 17, 18, 19],
y = 3 |  [ 20, 21, 22, 23]]]
我想在每一行{x=1,y=1,x=1,y=2,x=1,y=3,x=2,y=1,x=2,y=2,x=2,y=3}内插a=[1.3,1.8,2.34,2.9,3.45]的值,得到一个维度为2,3,5的三维数组:

[[[  0.3,  0.8,  1.34,  1.9,  2.45],
  [  4.3,  4.8,  5.34,  5.9,  6.45],
  [  8.3,  8.8,  9.34,  9.9, 10.45]],

 [[ 12.3, 12.8, 13.34, 13.9, 14.45],
  [ 16.3, 16.8, 17.34, 17.9, 18.45],
  [ 20.3, 20.8, 21.34, 21.9, 22.45]]]
目前,我使用for循环对x和y的每个组合进行迭代,并将我的3D数组的行馈送到numpy.iterpolate函数中,并将输出保存到另一个数组中;但是,对于大型阵列,这是非常缓慢的

# array is the 3D array with dimensions (l, n, m)
# x, y and z have length l, n and m respectively
# a is the values at which I wish to interpolate at with length b
# new_array is set up with dimensions (l, n, b) 

new_array = N.zeros(len(x)*len(y)*len(a)).reshape(len(x), len(y), len(a))
for i in range(len(x)):
      for j in range(len(y)):
               new_array[i,j,:] = numpy.interpolate(a, z, array[i,j,:])

任何帮助都将不胜感激

通过scipy.interpolate.griddata运行数据不需要for循环:


你考虑过SCIPY.Intual.GrDATA?我不认为有一个简单的方法…np.interp只接受1D输入,即使您尝试从头开始构建插值,np.searchsorted(查找要插值的存储单元的明显选项)也只适用于1D数组。是的,它只适用于2D,如果您阅读文档,它会声明您输入的点为N,ndim-同样,这需要一个for循环。嗨,谢谢你的回答。只有一件事,当我亲自尝试时,您使用的产品功能未被识别。这是一个numpy函数吗?我熟悉的numpy.prod函数不接受三个连续数组。谢谢。我忘了添加from itertools导入产品和scipy.interpolate导入griddata在代码顶部,编辑它!
>>> from itertools import product
>>>from scipy.interpolate import griddata

>>> data = np.arange(24).reshape(2, 3, 4)

>>> x = np.arange(1, 3)
>>> y = np.arange(1, 4)
>>> z = np.arange(1, 5)
>>> points = np.array(list(product(x, y, z)))

# This is needed if your x, y and z are not consecutive ints
>>> _, x_idx = np.unique(x, return_inverse=True)
>>> _, y_idx = np.unique(y, return_inverse=True)
>>> _, z_idx = np.unique(z, return_inverse=True)
>>> point_idx = np.array(list(product(x_idx, y_idx, z_idx)))
>>> values = data[point_idx[:, 0], point_idx[:, 1], point_idx[:, 2]]

>>> new_z = np.array( [1.3, 1.8, 2.34, 2.9, 3.45])
>>> new_points = np.array(list(product(x, y, new_z)))
>>> new_values = griddata(points, values, new_points)
>>> new_values.reshape(2, 3, -1)
array([[[  0.3 ,   0.8 ,   1.34,   1.9 ,   2.45],
        [  4.3 ,   4.8 ,   5.34,   5.9 ,   6.45],
        [  8.3 ,   8.8 ,   9.34,   9.9 ,  10.45]],

       [[ 12.3 ,  12.8 ,  13.34,  13.9 ,  14.45],
        [ 16.3 ,  16.8 ,  17.34,  17.9 ,  18.45],
        [ 20.3 ,  20.8 ,  21.34,  21.9 ,  22.45]]])