使用Python3中的scipy将多个洛伦兹人拟合到数据

使用Python3中的scipy将多个洛伦兹人拟合到数据,python,scipy,physics,curve-fitting,Python,Scipy,Physics,Curve Fitting,好吧,我很感激这需要一点耐心,但请容忍我。我正在分析一些拉曼光谱,并编写了一个程序的基础,使用Scipy曲线拟合将多个洛伦兹峰拟合到我的数据上。诀窍是我有这么多的数据,我想让程序自动识别洛伦兹人的初始猜测,而不是手动操作。总的来说,这个程序做得很好(并且可能对其他具有类似用例和更简单数据的人有用),但我不太了解Scipy,不足以优化曲线拟合,使其能够在许多不同的示例中工作 此处代码为回购: 图1显示了其工作良好的示例 问题的一部分是我的峰值查找算法,它有时很难为每个洛伦兹函数找到合适的起始位置。

好吧,我很感激这需要一点耐心,但请容忍我。我正在分析一些拉曼光谱,并编写了一个程序的基础,使用Scipy曲线拟合将多个洛伦兹峰拟合到我的数据上。诀窍是我有这么多的数据,我想让程序自动识别洛伦兹人的初始猜测,而不是手动操作。总的来说,这个程序做得很好(并且可能对其他具有类似用例和更简单数据的人有用),但我不太了解Scipy,不足以优化曲线拟合,使其能够在许多不同的示例中工作

此处代码为回购:

图1显示了其工作良好的示例

问题的一部分是我的峰值查找算法,它有时很难为每个洛伦兹函数找到合适的起始位置。您可以在图2中看到这一点

下一个问题是,出于某种原因,曲线拟合偶尔会发生灾难性的发散(我最好的猜测是由于舍入误差)。您可以在图3中看到这种行为

最后,虽然我通常会对每个洛伦兹曲线的高度和x位置进行很好的猜测,但我还没有找到预测曲线宽度或半高宽的好方法。预测这可能有助于曲线拟合

如果有人能以任何方式帮助解决这些问题,我将不胜感激。我愿意接受任何其他方法或建议,包括附加的第三方库,只要它们在当前实现的基础上有所改进。非常感谢任何尝试这一次的人

在这里,它完全按照我的意图工作:

下面您可以看到峰值查找方法无法识别所有峰值。有许多峰值查找算法,但我使用的是Scipy的“find_peaks_cwt()”(通常情况并非如此糟糕,这是一个极端情况)。

这里离这里太远了。这种情况经常发生,我真的无法理解为什么,也无法阻止它的发生。当我告诉它找到比光谱中可用的更多/更少的峰时,可能会发生这种情况,但这只是一个猜测。


我已经在Python3.5.2中完成了这项工作。PS我知道我不会在代码布局上赢得任何奖牌,但一如既往地欢迎对代码风格和更好实践的评论

我偶然发现了这个问题,因为我正试图解决完全相同的问题,下面是我的解决方案。对于每个峰值,我只在域+或-1/2到下一个最近峰值的距离的区域中拟合洛伦兹曲线。以下是我的函数,它确实可以分解域:

def get_local_indices(peak_indices):
#returns the array indices of the points closest to each peak (distance to next peak/2)
chunks = []

for i in range(len(peak_indices)):
    peak_index = peak_indices[i]
    if i>0 and i<len(peak_indices)-1:
        distance = min(abs(peak_index-peak_indices[i+1]),abs(peak_indices[i-1]-peak_index))
    elif i==0:
        distance = abs(peak_index-peak_indices[i+1])
    else:
        distance = abs(peak_indices[i-1]-peak_index)


    min_index = peak_index-int(distance/2)
    max_index = peak_index+int(distance/2)
    indices = np.arange(min_index,max_index)

    chunks.append(indices)

return chunks
def获取本地索引(峰值索引):
#返回距离每个峰值最近的点的数组索引(到下一个峰值的距离/2)
块=[]
对于范围内的i(len(峰值指数)):
峰值指数=峰值指数[i]

如果i>0且i do,您可以提前知道每个样本中有多少个峰值,或者这是您需要猜测的另一个参数?另外,一种避免图3所示发散的简单方法是将高度限制为正值。
curve\u fit
仅为快速曲线拟合提供了一个非常简单的界面。看一看,这是更灵活的-虽然更难使用。您需要指定一个成本函数,而不是曲线,这使您能够决定如何对异常值进行加权。此外,您可以指定边界和约束,这可能有助于散度。我事先不知道有多少个峰值,但我知道通常在3到6之间。如何对高度进行限制?我也会看看,谢谢!