2013-07-26 51 views
1

我想對python中的3d數組內的特定元素執行操作。下面是該陣列的一個示例:在Python中修改3D數組

[[[ 0.5   0.5  50.  ] 
    [ 50.5  50.5  100.  ] 
    [ 0.5  100.5  50.  ] 
    [ 135.   90.   45.  ]] 

[[ 50.5  50.5  100.  ] 
    [ 100.5   0.5  50.  ] 
    [ 100.5  100.5  50.  ] 
    [ 45.   90.   45.  ]] 

[[ 100.5  100.5  50.  ] 
    [ 100.5  100.5   0.  ] 
    [ 0.5  100.5  50.  ] 
    [ 90.   0.   90.  ]] 

的我需要到是採取陣列即0.5,0.5,50中看到的三個值,並從第4行即135採取的第一個元件的一個例子並將這四個元素髮送到一個函數中。該函數然後返回需要放入數組的3個元素的新值。

我對Python非常陌生,所以我很難讓它工作。我應該做一個循環?或者是其他東西?

感謝 尼克

在解決方案的嘗試:

b = shape(a) 
triangles = b[0] 

for k in range(0,triangles): 
    for i in range(0,2): 
     a[k,i,:] = VectMath.rotate_x(a[k,i,0],a[k,i,1],a[k,i,2],a[k,3,2]) 
+1

你嘗試的解決方案看起來很好。它工作嗎? – Luke

+0

它似乎到目前爲止,我只是不知道它是否是最好的方式來做到這一點 –

+0

如果它似乎工作,我會保持你的瞭解,因爲你知道它。如果你發現性能是一個問題,那麼你可能會發現使用numpy有幫助(例如,你可以將所有的三角形旋轉在一行而不是循環它們)。 – Luke

回答

1

你可以讓你的VectMath.rotate_x功能旋轉向量的數組,然後用切片a得到&投放數據:

a = np.array(
[[[ 0.5,   0.5,  50.,  ], 
    [ 50.5,  50.5,  100.,  ], 
    [ 0.5,  100.5,  50.,  ], 
    [ 135. ,  90. ,  45.,  ]], 
[[ 50.5,  50.5,  100.,  ], 
    [ 100.5,   0.5,  50.,  ], 
    [ 100.5,  100.5,  50.,  ], 
    [ 45. ,  90. ,  45.,  ]], 
[[ 100.5,  100.5,  50.,  ], 
    [ 100.5,  100.5,  0.,  ], 
    [ 0.5,  100.5,  50.,  ], 
    [ 90. ,   0. ,  90.,  ]]]) 

def rotate_x(v, deg): 
    r = np.deg2rad(deg) 
    c = np.cos(r) 
    s = np.sin(r) 
    m = np.array([[1, 0, 0], 
        [0, c,-s], 
        [0, s, c]]) 
    return np.dot(m, v) 

vectors = a[:, :-1, :] 
angles = a[:, -1, 0] 

for i, (vec, angle) in enumerate(zip(vectors, angles)): 
    vec_rx = rotate_x(vec.T, angle).T 
    a[i, :-1, :] = vec_rx 

print a 

輸出:

[[[ 5.00000000e-01 -3.57088924e+01 -3.50017857e+01] 
    [ 5.05000000e+01 -1.06419571e+02 -3.50017857e+01] 
    [ 5.00000000e-01 -1.06419571e+02 3.57088924e+01] 
    [ 1.35000000e+02 9.00000000e+01 4.50000000e+01]] 

[[ 5.05000000e+01 -3.50017857e+01 1.06419571e+02] 
    [ 1.00500000e+02 -3.50017857e+01 3.57088924e+01] 
    [ 1.00500000e+02 3.57088924e+01 1.06419571e+02] 
    [ 4.50000000e+01 9.00000000e+01 4.50000000e+01]] 

[[ 1.00500000e+02 -5.00000000e+01 1.00500000e+02] 
    [ 1.00500000e+02 6.15385017e-15 1.00500000e+02] 
    [ 5.00000000e-01 -5.00000000e+01 1.00500000e+02] 
    [ 9.00000000e+01 0.00000000e+00 9.00000000e+01]]] 

如果有很多三角形,如果我們可以旋轉所有沒有python循環的向量,速度可能會更快。

這裏我通過擴大矩陣產品的旋轉計算:

x' = x 
y' = cos(t)*y - sin(t)*z 
z' = sin(t)*y + cos(t)*z 

因此,我們可以向量化這些公式:

a2 = np.array(
[[[ 0.5,   0.5,  50.,  ], 
    [ 50.5,  50.5,  100.,  ], 
    [ 0.5,  100.5,  50.,  ], 
    [ 135. ,  90. ,  45.,  ]], 
[[ 50.5,  50.5,  100.,  ], 
    [ 100.5,   0.5,  50.,  ], 
    [ 100.5,  100.5,  50.,  ], 
    [ 45. ,  90. ,  45.,  ]], 
[[ 100.5,  100.5,  50.,  ], 
    [ 100.5,  100.5,  0.,  ], 
    [ 0.5,  100.5,  50.,  ], 
    [ 90. ,   0. ,  90.,  ]]]) 

vectors = a2[:, :-1, :] 
angles = a2[:, -1:, 0] 

def rotate_x_batch(vectors, angles): 
    rad = np.deg2rad(angles) 
    c = np.cos(rad) 
    s = np.sin(rad) 
    x = vectors[:, :, 0] 
    y = vectors[:, :, 1] 
    z = vectors[:, :, 2] 
    yr = c*y - s*z 
    zr = s*y + c*z 
    vectors[:, :, 1] = yr 
    vectors[:, :, 2] = zr 

rotate_x_batch(vectors, angles) 
print np.allclose(a, a2)