np.array交集//AttributeError:“模块"对象没有属性"PiecewisePolynomial" [英] np.array intersection // AttributeError: 'module' object has no attribute 'PiecewisePolynomial'

查看:64
本文介绍了np.array交集//AttributeError:“模块"对象没有属性"PiecewisePolynomial"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为python的初学者,我开始实现已经在Matlab中实现的想法.我想确定数组的交点(x,y坐标),而无需给出显式函数.也就是说,仅具有int值的数组可能与float坐标相交.因此,www会显示以下代码,请参见附件.

通过pip scipy interpolate 安装后,我无法解决即将发布的

  ERROR:AttributeError:模块"对象没有属性"PiecewisePolynomial". 

搜索功能没有帮助.

很高兴收到

的帮助

  1. 解决错误

或/和

  1. 以不同的方式计算交叉点(scipy是唯一方法吗?)

PS:由于在一定间隔内交集的唯一性,因此在matlab上通过差计算交集并不方便

 导入scipy.interpolate作为插值导入scipy.optimize为优化将numpy导入为npx1 = 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 =内插.PiecewisePolynomial(x1,y1 [:,np.newaxis])p2 =插值.PiecewisePolynomial(x2,y2 [:,np.newaxis])def pdiff(x):返回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)/2roots = set()对于x_mid中的val:root,infodict,ier,mesg = optimize.fsolve(pdiff,val,full_output =真)#ier == 1表示已找到根如果ier == 1且x_min< root< x_max:roots.add(root [0])roots =列表(roots)打印(np.column_stack((roots,p1(roots),p2(roots))))) 

解决方案

正如我在评论中指出的那样,您尝试使用的方法在较新的scipy版本中不可用,但未达到预期的效果它仍然可以执行.

我的建议是使用

关键步骤是检查 fsolve 的结果是否是新的(不接近您以前的根),并且您确实在给定的 x0 处找到了根.

或者,您可以使用在 xvals 中定义的间隔,检查每个间隔上的分段线性函数,并分析检查是否有两行具有这些参数(我的意思是 x1 = xvals [i],x2 = xvals [i + 1],y11 = f1 [x1],y12 = f1 [x2] 等)在给定线段上有一个交点.您可能可以向量化此方法,而不必担心结果的随机性,并且只需要注意数据中可能存在的奇异之处(其中 np.diff(xvals)很小,因此您需要除以这个.)


1 numpy.interp 没有定义插值器函数,而是直接计算网格上的插值.为了使用此函数执行相同的操作,您必须定义一个函数,该函数针对给定的 x 值调用 numpy.interp .由于归零搜索期间功能评估的次数众多,因此效率可能不如上面所述.

As a beginner in python, I started to implement an idea I already implemented in Matlab. I want to identify intersection points (x,y coordinates) of arrays, WITHOUT an explicit function given. That is, arrays with just int-values might have intersections with float-coordinates. Therefore the www presents the following code, see attachment.

After installing via pip scipy and interpolate, I can't solve the upcoming

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?)

PS: computing the intersection via difference on matlab was not expedient, due to uniqueness of intersections in some intervals

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.

My suggestion is to use numpy.interp1 or scipy.interpolate.interp1d to construct a linear interpolator of your functions, then use fsolve as you did to find all possible intersections. 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.

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.

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. 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).


1numpy.interp doesn't define an interpolator function, rather it directly computes the interpolated values on a grid. 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. This would likely be less efficient than the above, due to the high number of function evaluations during the zero search.

这篇关于np.array交集//AttributeError:“模块"对象没有属性"PiecewisePolynomial"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆