2016-12-10 3 views
9

X, Y 및 Z 좌표의 3D 배열을 감안할 때 numpy를 사용하여 3D 메쉬 경로로 변환하는 방법은 무엇입니까?numpy에서 3D 경로로 x, y, z 좌표의 배열을 변환하는 방법

import numpy 

def path_2d_numpy(x, y): 
    m1, m2 = numpy.meshgrid(x, y) 
    m1[1::2] = m1[1::2,::-1] 
    r = numpy.append(m1, m2) 
    r.shape = 2,-1 
    return r.T 

from matplotlib import lines 
from matplotlib import pyplot 

def plot_path_2d(path): 
    x, y = path.T 
    pyplot.plot(x, y, '-ro', lw=3) 
    pyplot.show() 

x = numpy.linspace(4, 1, 4) 
y = numpy.linspace(1, 5, 5) 
path = path_2d_numpy(x, y) 
plot_path_2d(path) 

출력한다 :

나는 (루프에 대한 예) NumPy와 사용하여 2D이 작업을 수행하기 위해 관리

2D mesh path

...하지만 3D 위해 그것을 할 수 없습니다 . (즉, NumPy와없이) 순수 파이썬 솔루션을 표시하는 것은 : 출력

import numpy 

def path_3d(x, y, z): 
    nb_points =len(x)*len(y)*len(z) 
    path = numpy.empty((nb_points, 3)) 

    xord, yord, i = True, True, 0 
    for zi in z: 
     for yi in y[::1 if yord else -1]: 
      for xi in x[::1 if xord else -1]: 
       path[i] = xi, yi, zi 
       i += 1 
      xord = not xord 
     yord = not yord 
    return path 

from matplotlib import pyplot 
from mpl_toolkits.mplot3d import Axes3D 

def plot_path_3d(path): 
    fig = pyplot.figure() 
    ax = fig.gca(projection='3d') 
    xx, yy, zz = path.T 
    ax.plot(xx, yy, zz, '-bo', lw=3) 
    pyplot.show() 

x = numpy.linspace(4, 1, 4) 
y = numpy.linspace(1, 5, 5) 
z = numpy.linspace(-3, 0, 3) 

path = path_3d(x, y, z) 
plot_path_3d(path) 

:

3D mesh path

Essencialy을, 내가 무엇을 찾고 있어요 것은 내가 위해 한 같은 path_3d의 NumPy와 구현을위한 path_2d_numpy.

내가 다루고있는 실제 배열이 상당히 크기 때문에이 코드가 필요합니다. numpy없이 그것을하는 것은 다만 너무 느리다.

답변

6

이게 어떻게 보이나요?

import numpy as np 

def path_3d_numpy(x, y, z): 
    coords = np.stack(np.meshgrid(x, y, z), axis=-1) # shape = (nx, ny, nz, 3) 
    coords[1::2,:,:] = coords[1::2,::-1,:] 
    coords[:,1::2,:] = coords[:,1::2,::-1] 
    return coords.reshape(-1, 3) # flatten out the other axes 

당신과 같은 매우 동일한 순서로 포인트를 반복하지 않습니다,하지만 당신은 마찬가지로, 당신의 2D 경우가

로 기록 될 수


주위에 몇 가지 지표를 교환하여 해당을 간단하게 고칠 수 진짜 과잉에 대한

def path_2d_numpy(x, y): 
    coords = np.stack(np.meshgrid(x, y), axis=-1) 
    coords[1::2] = coords[1::2,::-1] 
    return coords.reshape(-1, 2) 

, 당신은 N 차원이를 확장 할 수

def path_nd(*args): 
    coords = np.stack(np.meshgrid(*args), axis=-1) 
    N = len(args) 

    axes = np.arange(N) 
    for i in range(N-1): 
     # the last axis isn't part of our mesh, so don't roll it 
     rolled_axes = tuple(np.roll(axes, -i)) + (N,) 
     rolled_view = np.transpose(coords, rolled_axes) 
     rolled_view[1::2,:] = rolled_view[1::2,::-1] 

    return coords.reshape(-1, N)