Шляхи пришвидшити сценарії Python, що працюють як інструменти ArcGIS [закрито]


31

Це досить загальне питання. Мені просто цікаво, які поради та підказки програмісти ГІС використали для прискорення скриптів для архпій, які ви імпортуєте в панель інструментів і запускаєте.

Я щодня працюю над написанням невеликих сценаріїв, щоб допомогти користувачам, які не є ГІС, в моєму офісі обробляти дані ГІС. Я виявив, що загалом обробка 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. Вам потрібно перетворити посилання "buff" з файлової посилання на посилання "рівень 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, а потім створіть свій функціональний рівень проти джерела in_memory. Незважаючи на те, що початкова копія пам’яті може додати кілька секунд наперед, ви можете виявити, що ця обробка копіювальних функцій + табуляції_областей матиме швидший загальний час обробки, ніж ваша поточна модель.
RyanDalton

Я також спробував це, і, схоже, це рішення зробить процес циклу швидшим, але це не так. Створення шару функції в циклі призводить до приблизно 8-10 секунд на цикл, в той час як створення елементу шару до циклу призводить до 11 - 14 секунд на цикл. Я не надто впевнений, чому, оскільки ваше рішення звучить так, що воно обробляється швидше. У мене є 8 Гб оперативної пам’яті, тому я сумніваюся, що це буде проблема.
Коді Браун

Також обробка функцій в in_memory перед циклом, а потім все-таки створення шару функцій у циклі призводить до дещо швидшої продуктивності. Це майже залишається 8 секунд на ряд для кожного циклу. Що зменшить загальний час роботи з 26 годин до 22
Коді Браун

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

28

Загальні методи оптимізації пітона можуть заощадити значну кількість часу.

Одним із дійсно хороших методик визначення місця розташування у вашому сценарії є використання вбудованого модуля cProfile:

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

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

Загальні покажчики на швидший пітон код:

  • Розуміння списків, як правило, швидше, ніж циклічне
  • Генератори виробляють один предмет одночасно, а не виробляють весь список відразу
  • Використовуйте xrange замість діапазону в python 2 (не потрібно в 3)
  • Набори можуть виводити списки заздалегідь заздалегідь, коли йдеться про визначення того, який елемент присутній у наборі, але, як правило, повільніше, ніж списки, якщо мова йде про повторення над їх вмістом Джерело
  • Виклики функцій можуть бути дорогими для джерела продуктивності
  • Більше порад та деталей дивіться тут Підказки щодо ефективності Python та тут 10 Порад та проблеми оптимізації Python.

Що стосується вашого сценарію, я не можу коментувати аспекти ArcPy, оскільки у мене на цьому комп’ютері не встановлена ​​дуга, але ви, можливо, захочете спробувати використовувати цикл замість циклу часу, щоб побачити, чи це щось покращує. Також 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
Я використав два посилання, які ви залишили в останній кулі, і міг реально допомогти моєму сценарію з кількома швидкими виправленнями!
Коді Браун

Якби я міг присвоїти дві правильні відповіді, я би. Хоча ваша відповідь справді пропонувала багато ідей, як пришвидшити пітон, @RyanDalton запропонував ідеї, які мали найбільший вплив. Дякую тонну!
Коді Браун

13

Переконайтеся, що ви пишете на внутрішній диск на комп’ютері. Досягнення по всій мережі, коли це не потрібно, може дійсно уповільнити обробку. Можна навіть швидше скопіювати дані, як перший крок у процесі, щоб зберегти наступне читання-запис якомога швидше

Запуск сценарію повністю поза ArcMap може бути набагато швидшим. Якщо під час обробки карта не потрібна, не використовуйте ArcMap.


Я виявив, що запуск сценарію всередині моделі з ArcCatalog (сам по собі в Calculate Valueдіалоговому вікні) буде оброблятися швидше, ніж запуск того ж сценарію з вікна ArcPy в ArcMap. Це суто анекдотичне спостереження.
Сінді Джаякумар

1
Я вважаю, що мені потрібна карта, щоб Tabulate працював належним чином, але я спробую це. Якщо це працює за межами ArcMap, я думаю, що це пришвидшиться. Також я вже біжу з локального диска, що вже подвоїв швидкість сценарію.
Коді Браун

На жаль, Select не працює за межами ArcMap, і це необхідно, тому що мені потрібно зробити форму таблиці за формою.
Коді Браун

3
@ CodyBrown - Ви невірні щодо того, що Вибрати не працює поза сеансом ArcMap. Дивіться мою відповідь щодо використання інструменту MakeFeatureLayer.
RyanDalton

Раян має рацію. Коли інструмент вибору використовується самостійно, він створює подання таблиці або ваших просторових даних, або даних таблиці. Використовуючи його або в ModelBuilde, або в сценарії, ви повинні створити представлення даних, а у вашому випадку створити його за допомогою інструменту MakeFeatureLayer.
дчабоя

6

Це може не відповісти на ваше запитання щодо запуску інструментів ArcPy всередині ArcMap, але коли мені потрібно зробити деяку м'ясну обробку за допомогою інструментів геообробки та Python, я схильний запускати її за межами системи GIS за допомогою IDE PyScripter . Я виявив, що це працює швидше. Я також застосував RAMDISK для невеликих тимчасових наборів даних (трохи схожий на робочу область in_memory )

Ну, це мої головні поради! :)


2
Щоб дещо затуманити цю відповідь, під час запуску скриптів з Python IDE багато хто вводить функцію відстеження, щоб допомогти переглядати змінні та іншу допомогу з налагодження. Ця функція може масово уповільнити сценарії, якщо вона робить занадто багато, так як її називають ВСЕ ЧАС, а іноді вона встановлюється неявно без втручання користувача. Був певний патологічний випадок, який я спостерігав, коли сценарій Python в ArcMap запускався за 4 хвилини, тоді як той самий сценарій від Wing IDE займав 3 години. Як тільки він був запущений з Python.exe без крила, він повернувся до ~ 2–3-хвилинної території виконання.
Jason Scheirer

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.