Encuentra la intersección de dos conjuntos de datos discretos

Encuentra la intersección de dos conjuntos de datos discretos

Al realizar la investigación de un proyecto, a menudo es necesario resolver la intersección de dos conjuntos de datos discretos. Una práctica común es usar primero un modelo funcional como un modelo polinomial o un modelo exponencial para ajustar los dos conjuntos de datos discretos, obtener la función de ajuste y luego usar resolver para resolver la solución exacta de las dos curvas. Pero esto tiene una limitación obvia. Cuando los dos conjuntos de datos discretos no cumplen con ninguno de los modelos anteriores, la curva ajustada por el modelo anterior se desviará seriamente de los puntos de coordenadas de datos discretos reales, lo que provocará errores en los resultados de la solución. . Por lo tanto, este artículo resuelve la intersección de dos conjuntos de datos discretos (que se pueden considerar como dos funciones lineales por partes) y resume otro método de solución, que puede obtener directamente la intersección exacta de dos conjuntos de polilíneas de datos discretos (lineales).

La precisión de la resolución de la intersección de dos conjuntos de polilíneas de datos discretos descritos en este artículo está determinada por la densidad de los dos conjuntos de datos discretos proporcionados por el usuario. Cuanto más densos sean los dos conjuntos de datos discretos proporcionados por el usuario, más suave aparecerá la función lineal por partes (polilínea de datos discretos) y, naturalmente, mayor será la precisión de la solución obtenida.

(1) Encuentre la intersección de dos conjuntos de datos discretos (misma secuencia X)

Suponga que hay dos conjuntos de datos discretos (la misma secuencia X)

Grupo 1:

X = [1, 2, 3, 4, 5, 6, 7]
Y1 = [6, 5, 3, 10, 5, 6, 8]

Grupo 2:

X = [1, 2, 3, 4, 5, 6, 7]
Y2 = [2, 5, 5, 4, 3, 5, 8]

Los puntos de coordenadas de los dos grupos de datos discretos (la misma secuencia X) se muestran en la figura:

imagen-20210320012200092

Como se puede ver en la figura anterior, debe haber un total de 3 intersecciones entre los dos conjuntos de datos discretos, por lo que encontramos la intersección de los dos conjuntos de datos discretos, el código es el siguiente:

numpy_get_roots_with_two_piecewise_linear_by_same_X.py

import numpy as np
import matplotlib.pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号



#### 两组离散数据(同X)求交点 ####
def numpy_get_roots_with_two_piecewise_linear_by_same_X(
    Y1 = [6, 5, 3, 10, 5, 6, 8], 
    Y2 = [2, 5, 5, 4, 3, 5, 8], 
    X = None, 
    plot = 0
    ):
    # 注1:Y1与Y2长度相等,每条直线段最多只能有一个交点(不可能有两个)
    # 注1:X的值必须由小到大(X须为单调递增序列)
    if X == None:
        X = [i+1 for i in range(len(Y1))]
    else:
        pass
    
    roots = []
    for i in range(len(Y1)-1):
        Y_i_1 = [Y1[i], Y1[i+1]]
        Y_i_2 = [Y2[i], Y2[i+1]]
        X_i = [X[i], X[i+1]]

        poly_i_1 = np.poly1d(np.polyfit(X_i, Y_i_1, 1))
        poly_i_2 = np.poly1d(np.polyfit(X_i, Y_i_2, 1))
        poly_delta = poly_i_1 - poly_i_2
        
        # 非水平直线函数poly_delta必定有且只有一个解
        root_i = poly_delta.roots[0]
        y = poly_i_1(root_i)
        
        # 减少精度,找回因数据精度损失造成节点处丢失的根
        root_i = round(root_i, 6)
        y = round(y, 6)
        #print((root_i, y), X_i)
        if root_i >=  X_i[0] and root_i <= X_i[1]:
            #print((root_i, y), X_i)
            roots.append((root_i, y))

    if plot == 1:
        # 显示曲线
        plt.figure(figsize=(12, 6))
        plt.title('两组离散数据(相同序列X)求交点')
        plt.xlabel('X')
        plt.ylabel('Y')

        plt.plot(
            X, 
            Y1, 
            marker='*',
            label='X,Y1离散数据')

        plt.plot(
            X, 
            Y2, 
            marker='*',
            label='X,Y2离散数据')

        plt.legend()
        plt.show()

    roots = list(set(roots))
    roots.sort()
    return roots


if __name__ == '__main__':

    roots = numpy_get_roots_with_two_piecewise_linear_by_same_X(Y1=[6, 5, 3, 10, 5, 6, 8], Y2=[2, 5, 5, 4, 3, 5, 8], X=None, plot=1)
    print(roots)

Genere las coordenadas de la intersección de dos conjuntos de datos discretos (misma secuencia X):

[(2.0, 5.0), (3.25, 4.75), (7.0, 8.0)]

(2) Encuentre la intersección de dos conjuntos de datos discretos (secuencia diferente X)

Suponga que hay dos conjuntos de datos discretos (secuencia diferente X)

Grupo 1:

X1 = [1, 1.8, 3, 4, 5]
Y1 = [5, 5, 9, 10, 5]

Grupo 2:

X2 = [2, 3.2, 4.5, 5.1, 6, 8, 11]
Y2 = [8, 5, 5, 8, 3, 5, 4]

Los puntos de coordenadas de los dos grupos de datos discretos (secuencia X diferente) se muestran en la figura:

imagen-20210320012100475

Como puede verse en la figura anterior, debe haber 2 puntos de intersección en total entre los dos conjuntos de datos discretos.

Primero, convierta los dos conjuntos de datos discretos de diferentes secuencias X en dos conjuntos de datos discretos de la misma secuencia X como se muestra a continuación

imagen-20210320011934092

numpy_get_roots_with_two_piecewise_linear_by_same_X.pyLa función en la llamada nuevamente encuentra la intersección de dos conjuntos de datos discretos X en diferentes secuencias. El código es el siguiente:

import numpy as np
import matplotlib.pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号



from numpy_get_roots_with_two_piecewise_linear_by_same_X import *


# 求交集范围
def X1X2ab(X1ab=(1, 6), X2ab=(5,9)):
    '''
    xa, xb = X1X2ab(X1ab=(X1[0], X1[-1]), X2ab=(X2[0], X2[-1]))
    '''
    X1a = X1ab[0]
    X1b = X1ab[1]
    if X2ab == None:
        X2a = X1a
        X2b = X1b
    else:
        X2a = X2ab[0]
        X2b = X2ab[1]
        if X2a == None:
            X2a = X1a
        if X2b == None:
            X2b = X1b


    # 先确定X2a的位置 , r_left
    if X2a <= X1a:
        r_left = X1a
    elif X1a < X2a and X2a <X1b:
        r_left = X2a
    elif X2a >= X1b:
        return None
    # 再确定X2b的位置, r_right
    if X2b <= X1a:
       return None
    elif X1a < X2b and X2b <X1b:
        r_right = X2b
    elif X2b >= X1b:
        r_right = X1b
    xab = (r_left, r_right)
    return xab





def numpy_get_roots_with_two_piecewise_linear_any(

    X1 = [1, 1.8, 3, 4, 5],
    Y1 = [5, 5, 9, 10, 5],

    X2 = [2, 3.2, 4.5, 5.1, 6, 8, 11],
    Y2 = [8, 5, 5, 8, 3, 5, 4],

    plot = 0

    ):

    # 构造新的X_new
    X_ = X1 + X2
    X_.sort()
    X_new = []
    # 共同定义域
    a, b = X1X2ab(X1ab=(X1[0], X1[-1]), X2ab=(X2[0], X2[-1]))
    for i in X_:
        if i >= a and i <= b:
            X_new.append(i)
    X_new = list(set(X_new)) # 去重
    X_new.sort()
    #print(X_new)

    # 构造新的Y1_new、Y2_new
    Y1_new = np.interp(X_new, X1, Y1)
    Y2_new = np.interp(X_new, X2, Y2)

    roots = numpy_get_roots_with_two_piecewise_linear_by_same_X(Y1=Y1_new, Y2=Y2_new, X=X_new, plot=plot)
    return roots




if __name__ == '__main__':

    X1 = [1, 1.8, 3, 4, 5]
    Y1 = [5, 5, 9, 10, 5]

    X2 = [2, 3.2, 4.5, 5.1, 6, 8, 11]
    Y2 = [8, 5, 5, 8, 3, 5, 4]


    roots = numpy_get_roots_with_two_piecewise_linear_any(X1=X1, Y1=Y1, X2=X2, Y2=Y2, plot=1)
    print(roots)


    plt.figure(figsize=(12, 6))
    plt.title('两组离散数据(不同序列X)求交点')
    plt.xlabel('X')
    plt.ylabel('Y')

    plt.plot(
        X1, 
        Y1, 
        marker='*',
        label='X1,X1离散数据')

    plt.plot(
        X2, 
        Y2, 
        marker='*',
        label='X2,X2离散数据')

    plt.legend()
    plt.show()

Genere las coordenadas de la intersección de dos conjuntos de datos discretos (secuencia diferente X):

[(2.4, 7.0), (4.75, 6.25)]

Supongo que te gusta

Origin blog.csdn.net/caviar126/article/details/115019626
Recomendado
Clasificación