2012-08-07 98 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]]] 

(这是一个不同的结果,勃固省的答案)