python-3.x - 在定位地震时减少循环计算中使用的时间和内存
问题描述
我正在尝试定位震颤,这是一种幅度较小的地震。我使用网格搜索,这是一种找到“地震波到达的微分时间的理论值和观测值之间的差异”变得最小的坐标的方法。
我制作的代码如下。首先,我定义了两个函数来计算震源和网格上每个点之间的距离,以及使用 obspy 计算地震波的传播时间。
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
然后我使用以下代码进行网格搜索。
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]
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)
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是各台站东分量地震图列表。我必须获得“最终”列表才能继续下一步。
但是,问题是计算上面写的三段代码需要太多时间。此外,经过数十小时的计算,我得到的结果是“内存不足”错误消息。有没有可以减少时间和内存的解决方案?
解决方案
如果无法访问您的数据集,调试起来会有些困难,但这里有一些建议给您。
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 语句不应成为性能问题的根源,因为它过度分配:
/* 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())。
如果您使用更多详细信息更新您的问题,我可能会提供更详细的答案......希望这会有所帮助。
推荐阅读
- node.js - NodeJS在函数中调用readline
- scala - 监控具体集合的运行时使用
- javascript - 无法移除视频来源属性
- java - kotlin.TypeCastException: null 不能转换为非 null 类型 android.graphics.Bitmap
- ios - 在 iOS 上运行离子应用程序时出现 NSURLConnection 错误 1100
- amazon-web-services - 如何使两个ec2实例在内部相互连接
- php - TWIG PersistentCollection 无法转换为字符串:从 OneToMany 的表上输出数据 - ManyToOne 实体
- php - 我在 cron 作业中不断收到 HTTP 500 错误,同时它使用 ci3 中的电子邮件类在循环中发送电子邮件
- windows - 未为所有用户显示凭据提供程序(包括其他用户)
- javascript - 如何找到数组中第一个重复项的索引?