简体   繁体   English

np.array交集// AttributeError:“模块”对象没有属性“ PiecewisePolynomial”

[英]np.array intersection // AttributeError: 'module' object has no attribute 'PiecewisePolynomial'

As a beginner in python, I started to implement an idea I already implemented in Matlab. 作为python的初学者,我开始实现已经在Matlab中实现的想法。 I want to identify intersection points (x,y coordinates) of arrays, WITHOUT an explicit function given. 我想确定数组的交点(x,y坐标),而无需给出显式函数。 That is, arrays with just int-values might have intersections with float-coordinates. 也就是说,仅具有int值的数组可能与float坐标相交。 Therefore the www presents the following code, see attachment. 因此,www显示以下代码,请参见附件。

After installing via pip scipy and interpolate , I can't solve the upcoming 通过pip scipyinterpolate安装后,我无法解决即将出现的问题

ERROR: AttributeError: 'module' object has no attribute 'PiecewisePolynomial'.

Search function hasn't helped. 搜索功能没有帮助。

I would be very happy to receive some help by 我很高兴得到

  1. resolving the ERROR 解决错误

or/and 或/和

  1. computing the intersection differently (is scipy the only way?) 计算交集的方式不同(scipy是唯一方法吗?)

PS: computing the intersection via difference on matlab was not expedient, due to uniqueness of intersections in some intervals PS:由于在某些时间间隔内路口的唯一性,因此在Matlab上通过差计算路口并不方便

import scipy.interpolate as interpolate
import scipy.optimize as optimize
import numpy as np

x1=np.array([1.4,2.1,3,5.9,8,9,23])
y1=np.array([2.3,3.1,1,3.9,8,9,11])
x2=np.array([1,2,3,4,6,8,9])
y2=np.array([4,12,7,1,6.3,8.5,12])    

p1 = interpolate.PiecewisePolynomial(x1,y1[:,np.newaxis])
p2 = interpolate.PiecewisePolynomial(x2,y2[:,np.newaxis])

def pdiff(x):
    return p1(x)-p2(x)

xs=np.r_[x1,x2]
xs.sort()
x_min=xs.min()
x_max=xs.max()
x_mid=xs[:-1]+np.diff(xs)/2
roots=set()
for val in x_mid:
    root,infodict,ier,mesg = optimize.fsolve(pdiff,val,full_output=True)
    # ier==1 indicates a root has been found
    if ier==1 and x_min<root<x_max:
        roots.add(root[0])
roots=list(roots)        
print(np.column_stack((roots,p1(roots),p2(roots))))

As I noted in a comment, the method you were trying to use isn't available in newer versions of scipy, but it didn't do what you expected it to do anyway. 正如我在评论中指出的那样,您尝试使用的方法在较新版本的scipy中不可用,但是无论如何它并没有实现您期望的方法。

My suggestion is to use numpy.interp 1 or scipy.interpolate.interp1d to construct a linear interpolator of your functions, then use fsolve as you did to find all possible intersections. 我的建议是使用numpy.interp 1scipy.interpolate.interp1d构造函数的线性插值器,然后像您一样使用fsolve查找所有可能的交点。 Since fsolve (much like MATLAB's fzero ) can only find a single intersection at a time, you indeed need to loop over sections in your data to look for intersections. 由于fsolve (类似于MATLAB的fzero )一次只能找到一个交集,因此您确实需要循环遍历数据中的各个部分以寻找交集。

import scipy.interpolate as interpolate
import scipy.optimize as optimize
import numpy as np

x1 = np.array([1.4,2.1,3,5.9,8,9,23])
y1 = np.array([2.3,3.1,1,3.9,8,9,11])
x2 = np.array([1,2,3,4,6,8,9])
y2 = np.array([4,12,7,1,6.3,8.5,12])    

# linear interpolators
opts = {'fill_value': 'extrapolate'}
f1 = interpolate.interp1d(x1,y1,**opts)
f2 = interpolate.interp1d(x2,y2,**opts)

# possible range for an intersection
xmin = np.min((x1,x2))
xmax = np.max((x1,x2))

# number of intersections
xuniq = np.unique((x1,x2))
xvals = xuniq[(xmin<=xuniq) & (xuniq<=xmax)]
# note that it's bad practice to compare floats exactly
# but worst case here is a bit of redundance, no harm

# for each combined interval there can be at most 1 intersection,
# so looping over xvals should hopefully be enough
# one can always err on the safe side and loop over a `np.linspace`

intersects = []
for xval in xvals:
    x0, = optimize.fsolve(lambda x: f1(x)-f2(x), xval)
    if (xmin<=x0<=xmax
        and np.isclose(f1(x0),f2(x0))
        and not any(np.isclose(x0,intersects))):
        intersects.append(x0)

print(intersects)
print(f1(intersects))
print(f2(intersects))

Apart from a few runtime warnings from the more problematic sections of the algorithm, the above finds the two intersections of your functions: 除了算法中有问题的部分中的一些运行时警告外,以上内容还发现了函数的两个交集:

功能图

Key steps are checking that the results from fsolve are new (not close to your previous roots), and that you did actually find a root at the given x0 . 关键步骤是检查fsolve的结果是否是新的(不接近先前的根),并且确实在给定x0处找到了根。

Alternatively, you could use the intervals defined in xvals , check the piecewise linear functions on each interval, and check analytically whether two lines with these parameters (I mean x1=xvals[i],x2=xvals[i+1], y11=f1[x1], y12=f1[x2] etc) have an intersection on a given segment. 或者,您可以使用xvals定义的间隔,检查每个间隔上的分段线性函数,并分析检查是否有两行具有这些参数(我的意思是x1=xvals[i],x2=xvals[i+1], y11=f1[x1], y12=f1[x2]等)在给定线段上有一个交点。 You will likely be able to vectorize this approach, you won't have to worry about stochasticity in your results, and you only have to watch out for possible singularities in the data (where np.diff(xvals) is small, and you were to divide by this). 您可能可以向量化此方法,而不必担心结果的随机性,并且只需要注意数据中可能存在的奇点(其中np.diff(xvals)很小,而您除以此)。


1 numpy.interp doesn't define an interpolator function, rather it directly computes the interpolated values on a grid. 1 numpy.interp没有定义插值器函数,而是直接计算网格上的插值。 In order to do the same using this function, you would have to define a function that calls numpy.interp for the given x value. 为了使用此函数执行相同的操作,您必须定义一个函数,该函数针对给定的x值调用numpy.interp This would likely be less efficient than the above, due to the high number of function evaluations during the zero search. 由于归零搜索期间功能评估的数量众多,因此效率可能不及上述效率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM