Оптимизация скорости / сложности времени / масштабируемости двойных / вложенных циклов for в Python 3: itertools, parallelise, multiprocessing, concurrent - PullRequest
0 голосов
/ 09 июля 2020

У меня есть два набора медицинских данных Национальной службы здравоохранения Великобритании: df_oa, содержащий 181 000 пар координат, и df3, содержащий 8 000 пар координат.

Спецификация кода заключается в добавлении любых областей (df_oa.code) в пределах 3 км от врача (df3.Organisation_Code) для создания списка (хирургия_oa_list) вместе с измерением расстояния в километрах для итеративного построения матрицы. Порядок вывода не важен. Время работы без параллелизма в настоящее время оценивается примерно в 3-4 дня на 6-ядерном процессоре Intel Core i9 с тактовой частотой 2,9 ГГц и оперативной памятью DDR4 32 ГБ, 2400 МГц.

После изучения решений по оптимизации были предложены следующие предложения:

  • itertools (хотя для операции грубой силы, насколько я понимаю, это не повлияет на полноту времени)
  • concurrent.futures
  • multiprocessing.Pool

Однако с точки зрения оптимального решения, включая вычисления пула / потока, мне неясно, какое решение является оптимальным и какой порядок увеличения скорости может быть реально достигнут. Если у вас есть опыт в этой области, я был бы очень признателен за ваш совет и / или предложения по коду:

from geopy.distance import distance
surgery_oa_list = []
failed = []
outer = 0
for i in range(len(df3)):
    inner = 0
    results = 0
    processed = 0
    for j in range(len(oa_df)):
        try:
            d = distance((float(df3["Lat"][i]), float(df3["Lon"][i])), (float(oa_df["lat"][j]), float(oa_df["lon"][j]))).km
            processed += 1
            if d <= 3:
                surgery_oa_list.append([df3["Organisation_Code"][i], oa_df["code"][j], d])
                results += 1
        except Exception as e:
            print("failed :" + str([df3["Organisation_Code"][i], oa_df["code"][j]]))
            print("type error: " + str(e))
            failed.append([df3["Organisation_Code"][i], oa_df["code"][j], df3["Lat"][i], df3["Lon"][i], oa_df["lat"][j], oa_df["lon"][j]])
        if inner % 30000 == 0:
            print(str(outer) + ", " + str(inner))
        inner += 1
    print("hits: " + str(results))
    print("processed: " + str(processed))    
    outer += 1
print("done")
...