У меня есть код Python, который предназначен для принятия точечных шейп-файлов через следующий рабочий процесс:
- Точки слияния
- Объедините точки так, чтобы любые точки в пределах 1 м друг от друга становились одной точкой
- Создать векторный слой, где выбраны точки с z <10
- Буферные очки
- Разрешение полигона на растр 1м
- Реклассифицировать, где 1 - 9 = 1; NoData = 0
Каждый шейп-файл имеет от 250 000 до 350 000 точек, покрывающих ~ 5x7 км. Точечные данные, используемые в качестве входных данных, представляют собой местоположения деревьев. Каждая точка (т. Е. Дерево) имеет соответствующее значение "z", которое представляет радиус короны и используется в процессе буферизации. Мое намерение состоит в том, чтобы использовать окончательный двоичный вывод в отдельном процессе, чтобы создать растр, описывающий покрытие купола.
Я провел тест с четырьмя шейп-файлами, и он создал растр 700 МБ и занял 35 минут (процессор i5 и 8 ГБ ОЗУ). Видя, что мне нужно будет запустить этот процесс на 3500 шейп-файлах, я был бы признателен за любые советы по оптимизации этого процесса (см. Прилагаемый код). Вообще говоря, как лучше всего справиться с геообработкой больших данных? В частности, есть ли какие-либо изменения в коде или рабочем процессе, которые могут помочь повысить эффективность?
Редактировать :
Время (% от общего) для задач геообработки:
- Слияние = 7,6%
- Интеграция = 7,1%
- Особенность к Lyr = 0
- Буфер = 8,8%
- Поли в растр = 74,8%
- Реклассифицировать = 1,6%
# Import arcpy module
import arcpy
# Check out any necessary licenses
arcpy.CheckOutExtension("spatial")
# Script arguments
temp4 = arcpy.GetParameterAsText(0)
if temp4 == '#' or not temp4:
temp4 = "C:\\gdrive\\temp\\temp4" # provide a default value if unspecified
Reclassification = arcpy.GetParameterAsText(1)
if Reclassification == '#' or not Reclassification:
Reclassification = "1 9 1;NODATA 0" # provide a default value if unspecified
Multiple_Value = arcpy.GetParameterAsText(2)
if Multiple_Value == '#' or not Multiple_Value:
Multiple_Value = "C:\\t1.shp;C:\\t2.shp;C:\\t3.shp;C:\\t4.shp" # provide a default value if unspecified
# Local variables:
temp_shp = Multiple_Value
Output_Features = temp_shp
temp2_Layer = Output_Features
temp_Buffer = temp2_Layer
temp3 = temp_Buffer
# Process: Merge
arcpy.Merge_management(Multiple_Value, temp_shp, "x \"x\" true true false 19 Double 0 0 ,First,#,C:\\#########omitted to save space
# Process: Integrate
arcpy.Integrate_management("C:\\gdrive\\temp\\temp.shp #", "1 Meters")
# Process: Make Feature Layer
arcpy.MakeFeatureLayer_management(temp_shp, temp2_Layer, "z <10", "", "x x VISIBLE NONE;y y VISIBLE NONE;z z VISIBLE NONE;Buffer Buffer VISIBLE NONE")
# Process: Buffer
arcpy.Buffer_analysis(temp2_Layer, temp_Buffer, "z", "FULL", "ROUND", "NONE", "")
# Process: Polygon to Raster
arcpy.PolygonToRaster_conversion(temp_Buffer, "BUFF_DIST", temp3, "CELL_CENTER", "NONE", "1")
# Process: Reclassify
arcpy.gp.Reclassify_sa(temp3, "Value", Reclassification, temp4, "DATA")
источник
Ответы:
Некоторые изменения алгоритма, которые должны вам помочь.
Выполните ваш выбор, прежде чем объединить или интегрировать. Это значительно сократит расходы на более поздние функции.
Слияние и интеграция требуют больших затрат памяти, поэтому вы хотите продолжать исключать функции по мере того, как вы вводите классы пространственных объектов, и пытаться выполнять слияния в двоичном дереве, чтобы сохранить размер слияний и интеграций. например, для четырех шейп-файлов вы объединяете два шейп-файла и интегрируете их; объединить еще два шейп-файла и интегрировать; объединить два результирующих класса объектов и интегрировать.
Ваша очередь заданий начинается как очередь ссылок на шейп-файл. У вас также есть очередь результатов для размещения результатов. Метод run () для вашего работника параллельной обработки выполняет следующие операции: убирает из очереди два элемента. Если ничего не занято (очередь пуста), завершите работу. Если один элемент взят, поместите этот элемент прямо в очередь результатов.
Если для каждого элемента выбраны два элемента: если это шейп-файл, выберите для z <10 и создайте класс объектов in_memory; иначе, это уже класс объектов in_memory и пропускает шаг выбора. Объедините два класса объектов in_memory, чтобы создать новый класс объектов in_memory. Удалите исходные два класса объектов. Выполните интегрирование в новый класс пространственных объектов. Поместите этот класс объектов в очередь результатов.
Затем запустите внешний цикл while. Цикл начинается с очереди шейп-файла и проверяется на длину, превышающую 1. Затем он проходит очередь через рабочих. Если очередь результатов имеет длину больше 1, цикл while выполняет еще одну параллельную обработку, выполняемую для рабочих, пока очередь результатов не станет равной 1 классу объектов in_memory.
Например, если вы начинаете с 3500 шейп-файлов, ваша первая очередь будет иметь 3500 заданий. Второй будет иметь 1750 рабочих мест. 875, 438, 219, 110, 55, 28, 14, 7, 4, 2, 1. Ваше большое узкое место будет памятью. Если вам не хватает памяти (и вам не хватит памяти при создании первой очереди результатов, если это так), то измените ваш алгоритм, чтобы объединить более 2 классов объектов одновременно, а затем интегрируйте, что сократит размер вашей первой очереди результатов в обмен на более длительное время обработки. При желании вы можете написать выходные файлы и пропустить, используя классы объектов in_memory. Это значительно замедлит вас, но поможет преодолеть узкое место в памяти.
Только после выполнения слияния и интеграции всех шейп-файлов, заканчивающихся одним классом пространственных объектов, вы затем выполняете буферизацию, поли-растр и переклассификацию. Таким образом, эти три операции выполняются только один раз, и вы сохраняете свою геометрию простой.
источник
Первое, что я хотел бы сделать, это отслеживать использование ресурсов вашей системы с помощью Resource Monitor в Windows 7 или perfmon в Vista / XP, чтобы понять, привязаны ли вы к процессору , памяти или IO .
Если вы ограничены памятью или вводом-выводом, вы, вероятно, очень мало что можете сделать, кроме как модернизировать оборудование, уменьшить размер проблемы или полностью изменить подход.
Если вы решите, что вы привязаны к процессору, я бы поэкспериментировал с
multiprocessing
модулем или с одним из множества других доступных пакетов параллельной обработки на основе Python , чтобы посмотреть, сможете ли вы использовать больше ядер процессора для ускорения ваших операций.Хитрость многопроцессорности и параллелизма в целом заключается в нахождении хорошей схемы разбиения, которая:
Вы можете использовать сценарий, который я создал в этом ответе, в качестве отправной точки: Портировать код Avenue для создания Building Shadows в ArcPy / Python для ArcGIS Desktop?
Смотрите также этот блог ESRI, посвященный геообработке, на тему: Мультипроцессинг Python - подходы и соображения.
Я думаю, что ваш случай будет еще более сложным из-за более «черного ящика» природы используемых вами инструментов, а не из-за более мелкозернистых геометрических массивов, с которыми я работал. Возможно, работа с массивами NumPy может пригодиться.
Я также наткнулся на некоторые интересные материалы для чтения, если вы хотите посмотреть дальше arcpy:
источник