Сокращение времени и памяти, используемых в расчете l oop при локализации землетрясений - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь определить местонахождение тремора, который является типом землетрясения с меньшей амплитудой. Я использую поиск по сетке, который представляет собой метод, который находит координату, где «разница между теоретическим значением и наблюдаемым значением дифференциального времени в сейсмическом потоке c приход волны» становится минимальной.

Код, который я сделал следующим образом , Сначала я определил две функции, которые вычисляют расстояние между источником землетрясения и каждой точкой на сетке и которые рассчитывают время прохождения сейсмических c волн, используя 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 - список сейсмограмм восточных компонентов каждой станции. Мне нужно получить список 'final', чтобы перейти к следующему шагу.

Однако проблема в том, что для вычисления трех сегментов кодов, написанных выше, требуется слишком много времени. Более того, результат, который я получаю после десятков часов вычислений, - это сообщение об ошибке «недостаточно памяти». Есть ли решение, которое может сократить время и память?

1 Ответ

0 голосов
/ 14 февраля 2020

Без доступа к вашему набору данных это немного сложно отладить, но вот несколько советов для вас.

for i in range(len(di)):
    try:
        tt.append((latot[i],lotot[i],traveltime(dia[i])-traveltime(dib[i])))
    except IndexError:
        continue

• Учитывая размер этих списков, я думаю, что сборщик мусора может быть замедление этого цикла; Вы можете отключить его на время l oop (g c .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);

, но вы уже знаете размер массива, поэтому вы можете рассмотреть возможность использования numpy .zeroes (), чтобы заполнить список до for-l oop, и использовать индекс для непосредственной адресации каждого элемента. В качестве альтернативы, вы можете просто использовать списки, как вы делали ранее, и полностью избежать этой проблемы.

• Я вижу, что вы пометили вопрос с помощью python -3.x, поэтому range () должен Это не проблема, как это было в 2.x (иначе вы могли бы рассмотреть возможность использования xrange ()).

Если вы обновите свой вопрос с более подробной информацией, я, вероятно, мог бы дать более подробный ответ .. . надеюсь, это помогает.

...