2014-01-13 85 views
1

我有一個尺寸爲(l,n,m)的大尺寸三維numpy數組,其元素對應於x,y和z的一維數組,尺寸爲l,n和m。我想通過在x和y的每個組合的z值之間進行插值來找到給定值(長度爲b)的元素。這將給出尺寸(l,n,b)的輸出3D陣列。我想完整地使用numpy數組而不是訴諸for循環。避免for循環,在3D numpy數組的維上插值

例如,如果我的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至內插(x = 2,y = 2),(x = 2,y = 3),(x = 2,y = 3) = [1.3,1.8,2.34,2.9,3.45],得到尺寸的3D陣列(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,:]) 

任何幫助將不勝感激。

+0

你考慮scipy.interpolate.griddata? – usethedeathstar

+0

我不認爲有一種簡單的方法...''np.interp'只需要1D輸入,即使您嘗試從頭創建插值,'np.searchsorted',這是找到bin的明顯選項在其中插入,也只適用於一維數組。 – Jaime

+0

是的,它只適用於二維,如果你閱讀文檔(http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.griddata.html)它說明你輸入的點是( N,ndim) - 再次需要for循環。 – rjs1990

回答

0

你並不需要一個for循環,通過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]]]) 
+0

嗨,謝謝你的回答。只有一件事,當我自己嘗試時,您使用的產品功能無法識別。這是一個numpy功能嗎?我熟悉的numpy.prod()函數不需要連續三個數組。謝謝。 – rjs1990

+0

我忘了在代碼頂部添加'from itertools import product'和'from scipy.interpolate import griddata',編輯它! – Jaime