求两组离散数据的交集在做研究的时候,经常需要找到两组离散数据的交集。一种常见的做法是先用多项式模型或指数模型等函数模型拟合两组离散数据,得到拟合函数,然后用solve求出两条曲线的精确解。但这有一个明显的局限性。当两组离散数据不满足上述任一模型时,上述模型拟合的曲线将严重偏离实际离散数据坐标点,导致求解结果出现误差。很大。因此,本文求解两组离散数据的交点(可以看作是两个分段线性函数),总结出另一种求解方法,可以直接得到两组离散数据折线(线性)的精确交点。本文所描述的求解两组离散数据折线相交的精度是由用户给出的两组离散数据的密度决定的。用户给出的两组离散数据越密集,分段线性函数(离散数据折线)看起来越光滑,得到的解的精度自然也就越高。(1)两组离散数据(同序列X)的交点假设有这样两组离散数据(同序列X)第1组:X=[1,2,3,4,5,6,7]Y1=[6,5,3,10,5,6,8]第2组:X=[1,2,3,4,5,6,7]Y2=[2,5,5,4,3,5,8]两组离散数据(同序列X)的坐标点如图:从上图可以看出两组离散数据一共应该有3个交点,所以我们求两组离散数据的交点,代码如下:numpy_get_roots_with_two_piecewise_linear_by_same_X.py:importnumpyasnpimportmatplotlib.pyplotasplt#支持中文plt.rcParams['font.sans-serif']=['SimHei']#用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False#用来正常显示负号####两组离散数据(同X)交集####defnumpy_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必须是单调的递增序列)如果X==None:X=[i+1foriinrange(len(Y1))]else:passroots=[]foriinrange(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_deltamustThereonlyonesolutionroot_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)如果root_i>=X_i[0]且root_i<=X_i[1]:#print((root_i,y),X_i)roots.append((root_i,y))ifplot==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()returnn个根如果__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)输出两组离散数据(同序列X)的交点坐标:[(2.0,5.0),(3.25,4.75),(7.0,8.0)](2)两组离散数据(不同序列X)交点假设有两组离散数据(不同序列X)第1组:X1=[1,1.8,3,4,5]Y1=[5,5,9,10,5]第2组:X2=[2,3.2,4.5,5.1,6,8,11]Y2=[8,5,5,8,3,5,4]两组离散数据(不同序列x)坐标点如图:从上图可以看出,应该有2个总交集的离散数据集先将两组不同序列X的离散数据转换成两组相同序列X的离散数据如下图然后调用numpy_get_roots_with_two_piecewise_linear_by_same_X.py中的函数求两组不同序列X的离散数据的交点,即代码如下:importnumpyasnpimportmatplotlib.pyplotasplt#支持中文plt.rcParams['font.sans-serif']=['SimHei']#用来正常显示中文标签plt.rcParams['axes.unicode_minus']=False#用于正常显示负号fromnumpy_get_roots_with_two_piecewise_linear_by_same_Ximport*#求交集范围defX1X2ab(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]如果X2ab==None:X2a=X1aX2b=X1belse:X2a=X2ab[0]X2b=X2ab[1]ifX2a==None:X2a=X1aifX2b==None:X2b=X1b#首先判断X2a的位置,r_leftifX2a<=X1a:r_left=X1aelifX1a
