Python 对轨迹进行重采样,使其在每个样本中具有相等的欧几里德距离

Python 对轨迹进行重采样,使其在每个样本中具有相等的欧几里德距离,python,numpy,scipy,resampling,Python,Numpy,Scipy,Resampling,假设我们有一个x,y点的列表: x=[0,0,0] y=[0,10100] 点之间的欧几里德距离现在是[10,90]。 我正在寻找一个函数,它接受x,y和采样率,并且可以输出相等的距离点。e、 g: x=[0,0,0] y=[0,10100] 重采样距离=10 重采样,y,重采样距离 产出: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] [0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0] 使用类似的方法,我们可以获得几乎正确的值,但这并不

假设我们有一个x,y点的列表:

x=[0,0,0] y=[0,10100] 点之间的欧几里德距离现在是[10,90]。 我正在寻找一个函数,它接受x,y和采样率,并且可以输出相等的距离点。e、 g:

x=[0,0,0] y=[0,10100] 重采样距离=10 重采样,y,重采样距离 产出: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100] [0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0] 使用类似的方法,我们可以获得几乎正确的值,但这并不准确:

重新采样轨迹相同距离数据[0],数据[1],10 输出: [ 0. , 10.27027027, 20.81081081, 31.08108108, 41.62162162, 51.89189189, 62.43243243, 72.7027027 , 83.24324324, 93.78378378] [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]
使用任何第三方LIB(如numpy、scipy等)都可以。

正如许多评论所指出的,您需要更具体地说明如何处理不明确的情况。在您的示例中,x=[0,0,0];y=[0,10,100]这些值是10的倍数,因此它们可以整齐地相加。但是,您需要自己确定,当这些值加起来不整齐时,您希望如何处理这些情况

我写了一个函数,可以返回一个给定距离的所有点的x和y值,从第一个点开始,在两个点之间重新采样距离。也许这对你有帮助,可以作为在上面建立的基础

import numpy as np
from matplotlib import pyplot as plt

def resampler_2_points(p1, p2, resample_distance, include_endpoint=False):
    # get the distacne between the points
    distance_p1p2 = np.sqrt(  np.sum( (p2 - p1)**2 ) )
    
    # check for invalid cases
    if resample_distance > distance_p1p2:
        print("Resample distance larger than distance between points")
        return None
    
    elif distance_p1p2 == 0:
        print("Distance between the two points is 0")
        return None
    
    # if all is okay
    else:
        # get the stepsize of x and y coordinates
        stepsize_x, stepsize_y = (p2 - p1) * (resample_distance / distance_p1p2)
        
        # handle the case when a 'stepsize' along and axis equals 0  
        if stepsize_x == 0:
            y = np.arange(p1[1], p2[1], stepsize_y)
            x = np.zeros(len(y)) + p1[0]
        
        elif stepsize_y == 0:
            x = np.arange(p1[0], p2[0], stepsize_x)
            y = np.zeros(len(x)) + p1[1]
            
        # all other cases
        else:
            
            x = np.arange(p1[0], p2[0], stepsize_x)
            y = np.arange(p1[1], p2[1], stepsize_y)    
          
        # optionally append endpoint to final list
        if include_endpoint:
            x = np.append(x, p2[0])
            y = np.append(y, p2[1])
        
        # retrun the x and y coordinates in two arrays
        return x, y
下面是该函数在输出图中的使用示例

# set values (x and y coordiantes) for 2 points, and an resample distance
p1 = np.array([2,3])
p2 = np.array([20,15])
resample_distance = 4
x, y = resampler_2_points(p1, p2, resample_distance, include_endpoint=False)

plt.plot(x,y, 'o--r', label="Sampled points")
plt.scatter([p1[0], p2[0]], [p1[1], p2[1]], s=100, c='b', label="Input points")
plt.ylim((0,25))
plt.xlim((0,25))
plt.legend()
plt.show() 

正如许多评论所指出的,您需要更具体地说明如何处理不明确的情况。在您的示例中,x=[0,0,0];y=[0,10,100]这些值是10的倍数,因此它们可以整齐地相加。但是,您需要自己确定,当这些值加起来不整齐时,您希望如何处理这些情况

我写了一个函数,可以返回一个给定距离的所有点的x和y值,从第一个点开始,在两个点之间重新采样距离。也许这对你有帮助,可以作为在上面建立的基础

import numpy as np
from matplotlib import pyplot as plt

def resampler_2_points(p1, p2, resample_distance, include_endpoint=False):
    # get the distacne between the points
    distance_p1p2 = np.sqrt(  np.sum( (p2 - p1)**2 ) )
    
    # check for invalid cases
    if resample_distance > distance_p1p2:
        print("Resample distance larger than distance between points")
        return None
    
    elif distance_p1p2 == 0:
        print("Distance between the two points is 0")
        return None
    
    # if all is okay
    else:
        # get the stepsize of x and y coordinates
        stepsize_x, stepsize_y = (p2 - p1) * (resample_distance / distance_p1p2)
        
        # handle the case when a 'stepsize' along and axis equals 0  
        if stepsize_x == 0:
            y = np.arange(p1[1], p2[1], stepsize_y)
            x = np.zeros(len(y)) + p1[0]
        
        elif stepsize_y == 0:
            x = np.arange(p1[0], p2[0], stepsize_x)
            y = np.zeros(len(x)) + p1[1]
            
        # all other cases
        else:
            
            x = np.arange(p1[0], p2[0], stepsize_x)
            y = np.arange(p1[1], p2[1], stepsize_y)    
          
        # optionally append endpoint to final list
        if include_endpoint:
            x = np.append(x, p2[0])
            y = np.append(y, p2[1])
        
        # retrun the x and y coordinates in two arrays
        return x, y
下面是该函数在输出图中的使用示例

# set values (x and y coordiantes) for 2 points, and an resample distance
p1 = np.array([2,3])
p2 = np.array([20,15])
resample_distance = 4
x, y = resampler_2_points(p1, p2, resample_distance, include_endpoint=False)

plt.plot(x,y, 'o--r', label="Sampled points")
plt.scatter([p1[0], p2[0]], [p1[1], p2[1]], s=100, c='b', label="Input points")
plt.ylim((0,25))
plt.xlim((0,25))
plt.legend()
plt.show() 

我实现了下一个解决方案

为了提高效率,所有函数都由编译器/优化器/支持技术编译。无论何时启动Python代码,NUBA都会自动将所有由@ NUBA.NJIT装饰器标记的函数转换为纯代码,然后将C++代码编译成机器代码。在这些函数中没有与Python的交互,内部只使用低级的快速结构。因此,Numba通常能够将几乎任何代码的速度平均提高50-200倍,非常快!这种Python编译代码的速度通常非常接近纯C/C++中手工实现的相同算法的速度。要使用Numba,只需安装下两个python包:python-m pip install numpy Numba

接下来的步骤在我的代码中完成:

输入函数由两个一维数组x和y表示。 然后,输入函数点被两种分段函数之一以不同的方式调用或调用-1 2。 线性分段近似函数仅连接给定的点x0、y0数组,这样两个连续点x1、y1和x2、y2的对通过直线段连接。 三次样条曲线是更高级的平滑逼近函数的方法,它连接所有点x0、y0,使每对点x1、y1和x2、y2由表示为的三次线段连接,使其通过这两个端点加上公共点内相邻线段的一阶和二阶导数相等,这些都确保了函数看起来非常平滑和漂亮,并且在计算机图形学中非常流行,用于对函数/曲面进行自然/真实的近似/可视化。 然后用非常快的速度,我在这个插值函数上一个接一个地搜索点,每两个连续点之间的点正好等于算法值d所提供的期望值。 以上只是计算部分。其余步骤将使用matplotlib库可视化零件、绘制绘图。绘图的详细描述在绘图之前的代码后面。 为了使用此已实现的欧几里德等距离重采样算法,您只需导入我的下一个脚本模块并执行xr,yr=module\u name.resample\u euclid\u equidistx,y,dist,其中输入和输出x和y都是带浮点数的1D numpy数组,这将返回按dist欧几里德距离重采样的输入点。更多使用示例位于我的代码的测试函数中。第一次运行非常慢,可能需要15秒左右,这次运行只是一次编译运行,我所有的代码都会自动预编译为C/C++然后是机器代码,下一次运行非常快,特别是重采样函数本身只需要几毫秒。另外,为了只使用代码的计算部分,您需要安装python-mpipinstallnumpa,并运行我的全部代码,包括测试和可视化 只需运行我的脚本,您只需安装一次python-MPPIP安装numpy numba matplotlib


下面是结果图。以y=np.sinx*5+np.sin1+2.5*x*3+np.sin2+0.5*x*2为例,在50个均匀随机点上采样0I实现下一个解

为了提高效率,所有函数都由编译器/优化器/支持技术编译。无论何时启动Python代码,NUBA都会自动将所有由@ NUBA.NJIT装饰器标记的函数转换为纯代码,然后将C++代码编译成机器代码。在这些函数中没有与Python的交互,内部只使用低级的快速结构。因此,Numba通常能够将几乎任何代码的速度平均提高50-200倍,非常快!这种Python编译代码的速度通常非常接近纯C/C++中手工实现的相同算法的速度。要使用Numba,只需安装下两个python包:python-m pip install numpy Numba

接下来的步骤在我的代码中完成:

输入函数由两个一维数组x和y表示。 然后,输入函数点被两种分段函数之一以不同的方式调用或调用-1 2。 线性分段近似函数仅连接给定的点x0、y0数组,这样两个连续点x1、y1和x2、y2的对通过直线段连接。 三次样条曲线是更高级的平滑逼近函数的方法,它连接所有点x0、y0,使每对点x1、y1和x2、y2由表示为的三次线段连接,使其通过这两个端点加上公共点内相邻线段的一阶和二阶导数相等,这些都确保了函数看起来非常平滑和漂亮,并且在计算机图形学中非常流行,用于对函数/曲面进行自然/真实的近似/可视化。 然后用非常快的速度,我在这个插值函数上一个接一个地搜索点,每两个连续点之间的点正好等于算法值d所提供的期望值。 以上只是计算部分。其余步骤将使用matplotlib库可视化零件、绘制绘图。绘图的详细描述在绘图之前的代码后面。 为了使用此已实现的欧几里德等距离重采样算法,您只需导入我的下一个脚本模块并执行xr,yr=module\u name.resample\u euclid\u equidistx,y,dist,其中输入和输出x和y都是带浮点数的1D numpy数组,这将返回按dist欧几里德距离重采样的输入点。更多使用示例位于我的代码的测试函数中。第一次运行非常慢,可能需要15秒左右,这次运行只是一次编译运行,我所有的代码都会自动预编译为C/C++然后是机器代码,下一次运行非常快,特别是重采样函数本身只需要几毫秒。另外,为了只使用代码的计算部分,您需要安装python-m pip install numpy numba,为了运行我的全部代码(包括测试和可视化),只需运行我的脚本,您只需要安装python-m pip install numpy numba matplotlib一次


下面是结果图。以y=np.sinx*5+np.sin1+2.5*x*3+np.sin2+0.5*x*2为例,在50个均匀随机点上采样0,欧几里德距离为x1-x2**2+y1-y2**2+z1-z2**2**0.5相同距离的所有点都定义了一个圆,因此,这个问题不适定。@flabons欧几里德距离可用于任何维度。我不明白你们为什么说这个问题不恰当,你们能给我一些提示吗?问题是clear@flabons也许作者的本意不是要找到彼此距离相等的点,而是要找到两个相邻的x[i],y[i]和x[i+1],y[i+1]彼此之间具有相同给定距离的N个点。为了找到这N个点,使它们位于原始点的插值函数上。@JafarAkhondali顺便说一句,重采样数据意味着我们需要选择一些插值函数,例如线性/二次/三次或其他。因为根据选择,重采样点会有所不同。你知道你需要什么样的插值函数类型吗?或者任何非常精确的类型?欧几里德距离是x1-x2**2+y1-y2**2+z1-z2**2**0.5相同距离的所有点都定义了一个圆,因此该问题不适定。@flabons欧几里德距离可用于任何维度。我不明白你们为什么说这个问题不恰当,你们能给我一些提示吗?问题是clear@flabons也许作者的本意不是要找到彼此距离相等的点,而是要找到两个相邻的x[i],y[i]和x[i+1],y[i+1]彼此之间具有相同给定距离的N个点。找到这N个点,使它们位于原始点的插值函数上。@JafarAkho
ndali顺便说一句,重采样数据意味着我们需要选择一些插值函数,例如线性/二次/三次或其他。因为根据选择,重采样点会有所不同。你知道你需要什么样的插值函数类型吗?或者仅仅是任何非常精确的类型?我在2D位置数据上使用了这段代码,它在保持曲线形状和创建等距点方面做得非常出色-但是它改变了x值的范围。最初的范围是从-15到+15,但使用代码后,它变成了-15到+2.9。知道为什么会发生这种情况吗?另外,如果数组中有重复的值,它会因为被零除而中断。@CentauriAurelius您能提供一个最小的例子,说明x值发生变化时的几个点吗?我需要一些数据来测试和调试我的算法。关于第二个问题-在我的算法开始时删除重复项可以很容易地解决。@CentauriAurelius在使用我的函数之前和之后,您是否尝试过绘制结果?和我在回答中的情节一样。因为在我的例子中,输入X在[1;30]范围内,输出X在同一范围内。为了找出你的情况中的错误,我需要查看输入数据的最小示例,你能提供吗?我在2D位置数据上使用了这段代码,它在保持曲线形状和创建等距点方面做得非常好-但是它改变了我的x值范围。最初的范围是从-15到+15,但使用代码后,它变成了-15到+2.9。知道为什么会发生这种情况吗?另外,如果数组中有重复的值,它会因为被零除而中断。@CentauriAurelius您能提供一个最小的例子,说明x值发生变化时的几个点吗?我需要一些数据来测试和调试我的算法。关于第二个问题-在我的算法开始时删除重复项可以很容易地解决。@CentauriAurelius在使用我的函数之前和之后,您是否尝试过绘制结果?和我在回答中的情节一样。因为在我的例子中,输入X在[1;30]范围内,输出X在同一范围内。为了找出您的案例中的错误,我需要查看输入数据的最小示例,您能提供吗?