2012-08-07 171 views
1

我有一個數據數組,其中包含N個粒子的ndim座標,時間步長爲1到M.數組中的列通常表示每個粒子'p'的(x,y,z)和陣列中的每一行代表另一時間點「T」:2D到3D numpy陣列的高效轉換

x_t1p1 y_t1p1 z_t1p1 x_t1p2 y_t1p2 z_t1p2 ... x_t1pN y_t1pN z_t1pN 
x_t2p1 y_t2p1 z_t2p1 x_t2p2 y_t2p2 z_t2p2 ... x_t2pN y_t2pN z_t2pN 
... 
x_tMp1 y_tMp1 z_tMp1 x_tMp2 y_tMp2 z_t1p2 ... x_tMpN y_tMpN z_tMpN 

我想的數組轉換成3D格式,使得每個顆粒在不同的(m×NDIM)「片段」的numpy數組。我目前做如下:

import numpy as np 
def datarray_to_3D(data, ndim=3): 
    (nr,nc) = data.shape 
    nparticles = nc/ndim 
    dat_3D = np.zeros([nr,ndim,nparticles]) 
    for i in range(nparticles): 
     dat_3D[:,:,i] = data[:,i*ndim:(i+1)*ndim] 
    return dat_3D 

我有NumPy的基本知識,但想提高我的能力在數組操作。上述函數如何重寫以消除循環並使用更多的'NumPythonic'結構?

謝謝。

-c

回答

2

原始解決方案,與您的功能略有不同。

def datarray_to_3D(data, nparticles=3): 
    nr, nc = data.shape 
    data = data.reshape(nr, nparticles, nc/nparticles) 
    return np.rollaxis(data, 2, 1) 

更新:我已經更新了我原來的答覆,使我的錯誤更加清晰,感謝unutbu追趕它。我的解決方案以nparticles作爲參數,而不是ndim,其中nparticles * ndim == data.shape[1]。我犯了部分錯誤,因爲我更改了變量名稱ndim。在這種情況下,我會避免使用ndim作爲變量名稱,因爲它與屬性data.ndim(它是該數組的維數)太相似。這裏是更新後的解決方案,但是我已經替換了dim1`。它更像你的原始功能。

def datarray_to_3D(data, dim1=3): 
    nr, nc = data.shape 
    data = data.reshape(nr, nc/dim1, dim1) 
    return np.rollaxis(data, 2, 1) 
+0

謝謝!這正是我所尋找的,並讓我有機會探索重塑和rollaxis方法。 – cytochrome 2012-08-08 15:59:46

1

如何:

def alt_3D(data, ndim=3): 
    nr, nc = data.shape 
    result = data.reshape(nr,-1,3).transpose(0,2,1) 
    return result 

例如,如果

data = np.arange(18).reshape((-1,6)) 

然後alt_3D(data)產量:

[[[ 0 3] 
    [ 1 4] 
    [ 2 5]] 

[[ 6 9] 
    [ 7 10] 
    [ 8 11]] 

[[12 15] 
    [13 16] 
    [14 17]]] 

(這是一個不同的結果,勃固省的答案)