首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >减少定位地震时循环计算所用的时间和内存

减少定位地震时循环计算所用的时间和内存
EN

Stack Overflow用户
提问于 2020-01-16 06:22:35
回答 1查看 34关注 0票数 0

我正在尝试定位震动,这是一种振幅较小的地震。我使用网格搜索,这是一种找到“地震波到达的差分时间的理论值和观测值之间的差异”达到最小的坐标的方法。

我编写的代码如下所示。首先,我定义了两个函数来计算震源到网格上每个点的距离,并使用obspy来计算地震波的传播时间。

代码语言:javascript
运行
复制
def distance(a,i):
    return math.sqrt(((ste[a].stats.sac.stla-la[i])**2)+((ste[a].stats.sac.stlo-lo[i])**2))

def traveltime(a):
    return model.get_travel_times(source_depth_in_km=35, distance_in_degree=a, phase_list=["S"], receiver_depth_in_km=0)[0].time

然后,我使用以下代码进行了网格搜索。

代码语言:javascript
运行
复制
di=[(la[i],lo[i],distance(a,i), distance(b,i)) for i in range(len(lo))
    for a in range(len(ste))
    for b in range(len(ste)) if a<b]

didf=pd.DataFrame(di)

latot=didf[0]
lotot=didf[1]
dia=didf[2]
dib=didf[3]
代码语言:javascript
运行
复制
tt=[]
for i in range(len(di)):
    try:
        tt.append((latot[i],lotot[i],traveltime(dia[i])-traveltime(dib[i])))
    except IndexError:
        continue

ttdf=pd.DataFrame(tt)
代码语言:javascript
运行
复制
final=[(win[j],ttdf[0][i],ttdf[1][i],(ttdf[2][i]-shift[j])**2) for i in range(len(ttdf))
      for j in range(len(ccdf))]

其中la和lo是0.01度间隔的纬度和经度坐标列表,ste是每个台站的东向分量地震记录列表。我必须得到列表“最终”才能继续下一步。

然而,问题是计算上面写的三段代码需要太多的时间。此外,经过几十个小时的计算后,我得到的结果是'out out memory‘错误消息。有没有可以同时减少时间和内存的解决方案?

EN

回答 1

Stack Overflow用户

发布于 2020-02-15 04:44:44

如果不能访问您的数据集,调试会有些困难,但这里有一些建议。

代码语言:javascript
运行
复制
for i in range(len(di)):
    try:
        tt.append((latot[i],lotot[i],traveltime(dia[i])-traveltime(dib[i])))
    except IndexError:
        continue

·考虑到这些列表的大小,我认为垃圾收集器可能会降低for循环的速度;您可以考虑在循环期间将其关闭(gc.disable())。

·理论上,Append语句不应该是性能问题的根源,因为它过度分配:

代码语言:javascript
运行
复制
/* This over-allocates proportional to the list size, making room
 * for additional growth.  The over-allocation is mild, but is
 * enough to give linear-time amortized behavior over a long
 * sequence of appends() in the presence of a poorly-performing
 * system realloc().
 * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
 */
new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);

但是您已经知道了数组的大小,所以可以考虑在for循环之前使用numpy.zeroes()来填充列表,并使用索引直接寻址每个元素。或者,您可以只使用列表理解,就像您之前所做的,完全避免这个问题。

·我看到您已经用python-3.x标记了这个问题,所以range()应该不会像在2.x中那样成为问题(否则您会考虑使用xrange())。

如果您使用更多详细信息更新您的问题,我可能会提供更详细的answer...hope,这将有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59760405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档