簡體   English   中英

如何將n,y,z坐標數組轉換為numpy中的3D路徑

[英]How to convert arrays of x,y,z coordinates to 3D path in numpy

給定三個X,Y和Z坐標的1D陣列,如何使用numpy轉換為3D網格路徑?

我設法使用numpy(即沒有for循環)為2D做這個:

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)

哪個輸出:

2D網格路徑

...但是無法為3D做到這一點。 顯示純python解決方案(即沒有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網格路徑

Essencialy,我所尋找的是一個numpy的實施為我做了path_2d_numpy path_3d的。

我需要這個,因為我正在處理的實際數組非常大。 沒有numpy這樣做太慢了。

這看起來怎么樣?

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM