【问题标题】:Fitting arbitrary gaussian functions, massive memory consumption in python拟合任意高斯函数,python中的大量内存消耗
【发布时间】:2013-04-12 10:55:26
【问题描述】:

我正在尝试(在 python 中)将一系列任意数量的高斯函数(由仍在改进的简单算法确定)拟合到数据集。对于我当前的样本数据集,我有 174 个高斯函数。我有一个适合的程序,但它基本上是复杂的猜测和检查,并且会消耗所有 4GB 可用内存。

有什么方法可以使用 scipy 或 numpy 中的东西来完成此任务吗?

这是我尝试使用的,其中波长[] 是 x 坐标列表,fluxc[] 是 y 坐标列表:

#选择一个高斯 在范围(0,2)中重复: 对于范围内的 f(0,len(质心)): #遍历所有其他高斯 对于我在范围内(0,len(质心)): 如果我!= f: #对于每个波长, 对于 w 波长: #将每个的值附加到一个列表中,称为其他 others.append(height[i]*math.exp(-(w-centroid[i])**2/(2*width[i]**2))) #优化当前高斯的质心 上一页 = 质心 [f] 最佳 = 质心 [f] #选择一个数量级 对于范围内的 p (int(round(math.log10(centroid[i]))-3-repeat),int(round(math.log10(centroid[i])))-6-repeat,-1): #选择那个数量级的值 对于范围内的 m (-5,9): #改变当前项的值 质心[f] = prev + m * 10 **(p) #在所有波长上递增,列出新值 变异 = 0 残差 = 0 测试 = [] #在每个波长上增加并评估此变化是否使 R^2 更大 对于范围内的k(0,len(波长)): test.append(height[i]*math.exp(-(wavelength[k]-centroid[f])**2/(2*width[i]**2))) 残差 += (test[k]+others[k]-cflux[k])**2 变异性 += (test[k]+others[k]-avgcflux)**2 rsquare = 1-(残差/变异) #检查这个新拟合的 R^2 值 如果 rsquare > bestr: bestr = rsquare 最佳 = 质心 [f] 质心[f] = 最佳 #优化当前高斯的高度 上一页 = 高度[f] 最佳 = 高度 [f] #选择一个数量级 对于范围内的 p (int(round(math.log10(height[i]))-repeat),int(round(math.log10(height[i])))-3-repeat,-1): #选择那个数量级的值 对于范围内的 m (-5,9): #改变当前项的值 高度[f] = prev + m * 10 **(p) #在所有波长上递增,列出新值 变异 = 0 残差 = 0 测试 = [] #在每个波长上增加并评估此变化是否使 R^2 更大 对于范围内的k(0,len(波长)): test.append(height[f]*math.exp(-(wavelength[k]-centroid[i])**2/(2*width[i]**2))) 残差 += (test[k]+others[k]-cflux[k])**2 变异性 += (test[k]+others[k]-avgcflux)**2 rsquare = 1-(残差/变异) #检查这个新拟合的 R^2 值 如果 rsquare > bestr: bestr = rsquare 最佳 = 高度 [f] 高度[f] = 最佳 #优化当前高斯的宽度 上一页 = 宽度[f] 最佳 = 宽度 [f] #选择一个数量级 对于范围内的 p (int(round(math.log10(width[i]))-repeat),int(round(math.log10(width[i])))-3-repeat,-1): #选择那个数量级的值 对于范围内的 m (-5,9): 如果 prev + m * 10**(p) == 0: m+=1 #改变当前项的值 宽度[f] = prev + m * 10 **(p) #在所有波长上递增,列出新值 变异 = 0 残差 = 0 测试 = [] #在每个波长上增加并评估此变化是否使 R^2 更大 对于范围内的k(0,len(波长)): test.append(height[i]*math.exp(-(wavelength[k]-centroid[i])**2/(2*width[f]**2))) 残差 += (test[k]+others[k]-cflux[k])**2 变异性 += (test[k]+others[k]-avgcflux)**2 rsquare = 1-(残差/变异) #检查这个新拟合的 R^2 值 如果 rsquare > bestr: bestr = rsquare 最佳 = 宽度 [f] 宽度[f] = 最佳 计数 += 1 #print '{} of {} peaks 优化,迭代 {} of {}'.format(f+1,len(centroid),repeat+1,2) 完成=圆形(100 *(计数/(浮点数(len(质心))* 2)),2) print '{}% 完成'.format(完成) print 'New R^2 = {}'.format(bestr)

【问题讨论】:

    标签: python numpy scipy


    【解决方案1】:

    是的,使用 scipy 可能会做得更好(更容易)。但首先,将您的代码重构为更小的函数;它只是让阅读和理解正在发生的事情变得更加容易。

    至于内存消耗:您可能在某个地方过度扩展了一个列表(others 是一个候选者:我从来没有看到它被清除(或初始化!),而它被填充在一个四重循环中)。那,或者你的数据就是那么大(在这种情况下,你真的应该使用 numpy 数组,只是为了加快速度)。我不知道,因为您在不知道大小的情况下引入了各种变量(wavelengths 有多大?others 有多大?数据数组的所有初始化是什么以及在哪里?)

    另外,拟合 174 个高斯函数有点疯狂;要么寻找另一种方法来确定你想从数据中得到什么,要么把事情分开。从wavelengths 变量看来,您正在尝试将线条拟合到高分辨率光谱中;也许隔离大部分线并分别拟合这些孤立的组会更好。如果它们都重叠,我怀疑任何正常的拟合技术都会对您有所帮助。

    最后,也许像 pandas 这样的包可以提供帮助(例如,computation 子包)。

    也许最后一点,因为我看到代码中有很多可以改进的地方。在某些时候codereview 也可能有用。虽然现在我猜你的内存使用是最有问题的部分。

    【讨论】:

    • 感谢您的回复!这只是我编写的所有代码的三分之一左右,一切都在早些时候初始化。它用于分析高分辨率光谱,目前有 992 个数据点。是不是太多了?我想尽量避免在分析数据之前对其进行分解,以便尽可能多地提取有用的数据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2014-01-04
    • 2012-07-03
    • 1970-01-01
    相关资源
    最近更新 更多