1

我有一个数据数组,其中包含 N 个粒子在时间步长 1 到 M 上的 ndim 坐标。数组中的列通常代表每个粒子“p”的 (x,y,z),数组中的每一行代表另一个时间点' t':

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 格式,以便每个粒子位于 numpy 数组的不同(M x ndim)“切片”中。我目前正在执行以下操作:

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

4

2 回答 2

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作为一个论点而不是ndimwhere nparticles * ndim == data.shape[1]。我犯了这个错误,部分原因是我更改了变量的名称ndim。在这种情况下,我会避免ndim用作变量名,因为它data.ndim与数组维数的属性过于相似。这是更新的解决方案,但我已经替换ndim by了 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)
于 2012-08-07T17:44:46.657 回答
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]]]

(这与 Bago 的答案不同。)

于 2012-08-07T18:50:45.447 回答