Способы ускорения работы скриптов Python, работающих как инструменты ArcGIS [закрыто]


31

Это довольно общий вопрос. Мне просто интересно, какие советы и хитрости использовали ГИС-программисты для ускорения скриптов arcpy, которые вы импортируете в набор инструментов и запускаете.

Я каждый день работаю над написанием небольших сценариев, чтобы помочь не-ГИС-пользователям в моем офисе обрабатывать ГИС-данные. Я обнаружил, что обработка ArcGIS 10.0 в целом медленнее, чем 9.3.1, и иногда она становится еще медленнее при запуске скрипта Python.

Я собираюсь перечислить конкретный пример сценария, выполнение которого занимает более 24 часов. Это цикл, который табулирует область растра в буфере для каждой фигуры в буфере. Буфер имеет около 7000 фигур. Я не верю, что это должно длиться так долго.

while x <= layerRecords:

    arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
    arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
    TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

    arcpy.AddMessage ("          - Row: " + str(x) + " completed")
    x = x + 1
    z = z + 1

Прежде чем кто-либо скажет это, я запустил табулирование области для всего буфера, но он выдает ошибки, если выполняется более 1 записи. Это некорректный инструмент, но я должен его использовать.

В любом случае, если у кого-то есть идеи, как оптимизировать или ускорить этот скрипт, это было бы очень ценно. В противном случае, есть ли у вас какие-либо приемы ускорения работы с Python при использовании в ArcGIS?

Ответы:


26

Пара потенциальных предложений, которые помогут ускорить ваш процесс:

  1. Выбрать слой по атрибуту можно в скрипте только для Python, даже не запуская ArcGIS Desktop. Вам необходимо преобразовать ссылку «положительный» из ссылки на основе файла в ссылку «слой ArcGIS», с которой ArcGIS может обрабатывать запросы выбора. Используйте arcpy.MakeFeatureLayer_management ("buff", "buff_lyr") над циклом "while", а затем измените ссылки ниже цикла while, чтобы использовать "buff_lyr".

  2. Обработайте как можно больше ваших операций GP, используя рабочее пространство in_memory ... Используйте arcpy.CopyFeatures_management (shapefile, "in_memory \ memFeatureClass"), чтобы переместить ваш источник в память. Это хорошо работает, только если у вас достаточно ОЗУ для чтения всех классов объектов, которые вам нужны, в память. Помните, однако, что есть некоторые операции GP, которые не могут быть выполнены с использованием рабочей области in_memory (например, инструмент Project).

Из статьи онлайн-справки ArcGIS 9.3 « Промежуточные данные и рабочее пространство » (обратите внимание, этот язык был удален из справки 10.0 и 10.1):

ПРИМЕЧАНИЕ. В рабочую область in_memory можно записывать только таблицы и классы пространственных объектов (точки, линии, многоугольники). Рабочая область in_memory не поддерживает расширенные элементы базы геоданных, такие как подтипы, домены, представления, топологии, геометрические сети и наборы сетевых данных. Только простые функции и таблицы могут быть написаны.

Из интерактивной справочной статьи ArcGIS 10.1 « Использование рабочей области в памяти »:

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

  • Данные, записанные в рабочее пространство в памяти, являются временными и будут удалены при закрытии приложения.
  • Таблицы, классы пространственных объектов и растры могут быть записаны в рабочую область в памяти.
  • Рабочая область в памяти не поддерживает расширенные элементы базы геоданных, такие как подтипы, домены, представления, топологии, геометрические сети и наборы сетевых данных.
  • Наборы классов объектов или папки не могут быть созданы в рабочей области в памяти.

1
Это чудесно! Я искал способ использовать выборки за пределами ArcMap, но пока не увенчался успехом. С точки зрения этой проблемы, это фактически сократило мое время на строку до 13 секунд с 20 секунд. Но я быстро проделал другую работу и сделал MakeFeatureLayer внутри цикла, и он опустился до 9 секунд. Я сделал это, создав элемент из каждой фигуры, а не из таблицы векторного слоя. Я все еще хотел бы продолжить это, если это возможно, но уже это гораздо более быстрый процесс!
Коди Браун

Как упоминалось в # 2, используйте CopyFeatures, чтобы сделать копию ваших исходных данных in_memory, а затем создайте свой feature_layer для источника in_memory. Хотя первоначальное копирование в память может быть добавлено на пару секунд вперед, вы можете обнаружить, что эта обработка copyfeatures + tabulate_areas должна иметь более быстрое общее время обработки, чем ваша текущая модель.
RyanDalton

Я тоже это попробовал, и кажется, что это решение ускорит процесс цикла, но это не так. Создание векторного слоя в цикле дает примерно 8-10 секунд на цикл, а создание векторного слоя до того, как цикл дает 11 - 14 секунд на цикл. Я не совсем уверен, почему, поскольку ваше решение звучит так, как будто оно будет работать быстрее. У меня 8 ГБ оперативной памяти, поэтому я сомневаюсь, что это будет проблемой.
Коди Браун

Копирование объектов в in_memory перед циклом и последующее создание векторного слоя в цикле приводит к несколько более высокой производительности. Это в значительной степени остается 8 секунд на строку для каждого цикла. Что сократит общее время процесса с 26 часов до 22.
Коди Браун

После добавления ваших идей мой сценарий значительно улучшился. Огромное спасибо за вашу помощь и помощь всем!
Коди Браун

28

Общие методы оптимизации Python могут сэкономить вам значительное количество времени.

Одним из действительно хороших методов для определения того, где находятся задержки в вашем скрипте, является использование встроенного модуля cProfile:

from cProfile import run
run("code") # replace code with your code or function

Тестирование с использованием небольшой выборки данных позволит вам определить, какие вызовы функций занимают больше всего времени.

Общие указатели для более быстрого кода на Python:

  • Понимание списка обычно быстрее, чем зацикливание
  • Генераторы производят один элемент за раз вместо того, чтобы создавать весь список сразу
  • Используйте xrange вместо range в python 2 (не обязательно в 3)
  • Наборы могут выводить списки преформ, когда дело доходит до определения, присутствует ли элемент в наборе, но, как правило, медленнее, чем списки, когда дело доходит до перебора их содержимого. Source
  • Вызовы функций могут быть дорогостоящими для источника производительности
  • Дополнительные советы и подробности смотрите здесь Python Perfomance Tips и здесь 10 советов и вопросов по оптимизации Python

Что касается вашего скрипта, я не могу комментировать аспекты ArcPy, так как у меня не установлена ​​Arc на этом компьютере, но вы можете попробовать использовать цикл for вместо цикла while, посмотрите, улучшит ли это что-нибудь. Также x = x + 1 можно записать как x + = 1:

for record in layerRecords:
arcpy.SetProgressorLabel("Tabulating Row: " + str(x) + " of " + str(ELClayerRecords))
arcpy.SelectLayerByAttribute_management(Buff,"NEW_SELECTION", "Recno = " + str(x))                                  # Selecting the record
TabulateArea(Buff, "Recno", MatGRID, "VALUE", ScratchWS + "/tab" + str(z) +".dbf", nMatGRIDc)                          # Tabulate the area of the single row

arcpy.AddMessage ("          - Row: " + str(x) + " completed")
x+=1
y+=1

1
Я использовал две ссылки, которые вы оставили в своей последней статье, и смог действительно помочь моему сценарию с несколькими быстрыми исправлениями!
Коди Браун

Если бы я мог дать два правильных ответа, я бы. В то время как ваш ответ действительно предлагал много идей о том, как ускорить Python, @RyanDalton предложил идеи, которые оказали наибольшее влияние. Благодаря тонну!
Коди Браун

13

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

Запуск скрипта полностью вне ArcMap может быть намного быстрее. Если карта не требуется во время обработки, не используйте ArcMap.


Я обнаружил, что запуск скрипта внутри модели из ArcCatalog (сам по себе внутри Calculate Valueдиалога) будет происходить быстрее, чем запуск этого скрипта из окна ArcPy в ArcMap. Это чисто анекдотическое наблюдение, хотя.
Синди Джаякумар

1
Я считаю, что мне нужна карта для правильной работы Tabulate, но я собираюсь попробовать это. Если это работает вне ArcMap, я уверен, что это ускорится. Также я уже запускаю локальный диск, который уже удвоил скорость работы скрипта.
Коди Браун

К сожалению, выбор не работает за пределами ArcMap, и это необходимо, потому что мне нужно делать табулирование фигуры по фигуре.
Коди Браун

3
@ CodyBrown - Вы ошибаетесь в том, что Select не работает вне сеанса ArcMap. Смотрите мой ответ об использовании инструмента MakeFeatureLayer.
RyanDalton

Райан прав. Когда инструмент выбора используется сам по себе, он создает табличное представление ваших пространственных или табличных данных. Когда вы используете его в ModelBuilde или в скрипте, вы должны создать представление, а в вашем случае создать его с помощью инструмента MakeFeatureLayer.
dchaboya

6

Это может не ответить на ваш вопрос о запуске инструментов ArcPy внутри ArcMap, но когда мне нужно выполнить некоторую сложную обработку с помощью инструментов геообработки и Python, я склонен запускать ее вне системы ГИС с использованием IDE PyScripter . Я обнаружил, что он работает быстрее. Я также использовал RAMDISK для небольших временных наборов выходных данных (немного похоже на рабочее пространство in_memory )

Ну, они мои главные советы! :)


2
Чтобы несколько запутать этот ответ, при запуске сценариев из IDE Python многие внедряют функцию отслеживания, чтобы помочь в наблюдении за переменными и другой различной помощи при отладке. Эта функция может значительно замедлить работу сценариев, если она делает слишком много, поскольку она называется ВСЕ ВРЕМЯ, и иногда она устанавливается неявно без вмешательства пользователя. Я наблюдал один патологический случай, когда скрипт Python, запускаемый в ArcMap, запускался за 4 минуты, в то время как тот же скрипт из Wing IDE занимал 3 часа. Как только он был запущен из Python.exe без Wing, он вернулся к ~ 2-3 минутной среде выполнения.
Джейсон Шайрер,

1
У меня была головная боль при настройке моих скриптов на ArMap, иногда я не мог полностью, пока я не обратился к Pyscripter, это может сократить время выполнения по сравнению с Arcmap, без использования какого-либо совета по оптимизации.
Geogeek

@JasonScheirer ты нашел в Wing твик, чтобы отключить это? Я уверен, что есть один.
Кертис Прайс

5

Попробуйте закомментировать arcpy.SetProgressorLabel и посмотрите, насколько вы ускорились. Я обнаружил, что любой вывод на экран, вплоть до ошеломления DOS, резко замедляет время обработки. Если вам действительно нужно увидеть этот вывод, попробуйте показать его каждый N-й цикл.


4

Убедитесь, что вы удалили все import xxxxстроки, которые не используются.

(т.е. если вы еще не используете математические функции import Math, это займет некоторое время после загрузки скрипта)

Хотя это не окажет большого влияния на отдельные скрипты, которые запускаются (например, ваши), это повлияет на любые скрипты, которые запускаются часто и периодически.


7
Я сомневаюсь, что любому стандартному модулю Python требуется более тысячи раз, чтобы инициализировать модуль arcpy.
blah238

1
@ blah238 import Mathбыл плохим примером. Однако для загрузки некоторых из более крупных библиотек ArcPy требуется значительное количество времени.
nagytech

1
это все равно сбрасывает только секунды (максимум!), а не часы
Майк Т

1
@MikeToews Для сценариев, которые запускаются часто и повторяются, несколько секунд складываются в течение нескольких дней / недель и т. Д. Хотя это не решает основной проблемы ОП, он попросил дать общие советы.
nagytech
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.