【问题标题】:How to convert arrays of x,y,z coordinates to 3D path in numpy如何在numpy中将x,y,z坐标数组转换为3D路径
【发布时间】:2016-12-10 13:17:37
【问题描述】:

给定X、Y、Z坐标的三个1D数组,如何使用numpy转换成3D网格路径?

我设法使用 numpy 为 2D 做到这一点(即没有 for 循环):

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)

哪个输出:

...但无法为 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)

哪个输出:

本质上,我正在寻找的是 path_3d 的 numpy 实现,就像我为 path_2d_numpy 所做的那样。

我需要这个,因为我正在处理的实际数组非常大。在没有 numpy 的情况下这样做太慢了。

【问题讨论】:

    标签: python numpy path 3d mesh


    【解决方案1】:

    这看起来怎么样?

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 2010-11-25
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多