Як підвищити продуктивність при використанні курсорів ArcGIS в Python з великими таблицями?


10

У мене досить великий клас функціональних класів у базі даних геоданих (~ 4 000 000 записів). Це звичайна сітка точок з роздільною здатністю 100 м.

Мені потрібно виконати своєрідне узагальнення на цьому шарі. Для цього я створюю нову сітку, де кожна точка лежить посередині 4 "старих" точок:

 *     *     *     *
    o     o     o
 *     *     *     *
    o     o     o
 *     *     *     *

[*] = точка вихідної сітки - [о] = точка нової сітки

Значення атрибута кожної нової точки обчислюється на основі зважених значень 4-х сусідів у старій сітці. Таким чином, я петлю на всіх точках моєї нової сітки і, для кожної з них, я петлю на всі точки моєї старої сітки, щоб знайти сусідів (порівнюючи значення X і Y в таблиці атрибутів). Як тільки 4 сусідки знайдені, ми виходимо з петлі.

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

Чи бачите ви можливість зробити це більш ефективним? Кілька ідей на моїй голові:

  • Індексуйте поля X і Y => Я це зробив, але не помітив суттєвих змін у продуктивності
  • Зробіть просторовий запит, щоб знайти сусідів, а не на основі атрибутів. Це б насправді допомогло? Яка просторова функція в ArcGIS повинна виконувати цю роботу? Я сумніваюся, що, наприклад, буферизація кожної нової точки виявиться більш ефективною
  • Перетворіть клас функції в масив NumPy. Чи допомогло б це? Я до цього часу не працював багато з NumPy, і я не хотів би занурюватися в нього, якщо хтось не скаже мені, що це дійсно може допомогти скоротити час обробки
  • Ще щось?

Яку версію Arcmap ви використовуєте?
Мартін

Чи розглядали Ви PostGIS? Це варіант?
Чад Купер

Вибачте, що я забув: ArcGIS 10.1 // Python 2.7
Stéphane Henriod

Ні, PostGIS, на жаль, не є варіантом, мої руки, на жаль, дуже прив’язані тут ... У кращому випадку я можу використовувати Oracle з функціями SDE
Stéphane Henriod

Відповіді:


13

Що робити, якщо ви ввели точки в нумерований масив і використовували scipy cKDTree для пошуку сусідів. Я обробляю хмари точок LiDAR з великою кількістю точок (> 20 мільйонів) протягом декількох Хвилин за допомогою цієї методики. Існує документація тут для kdtree і тут для Numpy перетворення. В основному ви читаєте х, у в масив і повторюєте кожну точку в масиві, знаходячи індекси точок на певній відстані (околиці) кожної точки. Ви можете використовувати ці індекси для обчислення інших атрибутів.


ця відповідь краща за мою
radouxju

Мені подобається ця ідея, але у мене немає науково-дослідної роботи на робочій станції, над якою я працюю (і прав адміністратора немає). Якщо мені вдасться встановити цей пакет, я спробую його спробувати
Stéphane Henriod

4

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

Якщо ви не хочете мати клопоту з numpy, просто складіть простий словник python, де ви використовуєте свої координати як просту текстову клавішу, і заповніть атрибути, необхідні для обчислення, у список як значення елементу словника.

На другому кроці ви можете легко отримати значення, необхідні для обчислення точки, просто отримавши їх зі свого словника (що неймовірно швидко, через словники hashindex елементів).


Мені справді подобається ваша ідея зі словниками, і я її просто реалізував. Дійсно працює набагато краще ... поки я фактично не напишу результати з row.insertRow () ... Будь-яка ідея, як я можу вдосконалити цю частину?
Стефан Генріод

У мене була подібна проблема, коли мені довелося вибрати 10 000 балів із 14 мільйонів. а потім видаліть його. arcpy.cursors, де тільки вдається видалити близько 1 або 2 балів за секунду (!). тому я встановив модуль pyodbc, щоб видалити їх за допомогою однієї заяви SQL DELETE лише за одну секунду. ОНОВЛЕННЯ через SQL принесе вам багато вдосконалень, якщо ви хочете лише змінювати атрибути ... все ж вам доведеться встановлювати додаткові модулі пітона ... але це того варте.
Юрген Зорніг

2

Для звичайної сітки працювати набагато ефективніше в растровому форматі. Перетворіть свою першу сітку в растрову, ви можете повторно проводити вибірку з тією ж роздільною здатністю, використовуючи білінеарний інтерполятор, але зміщуючи вихідне зображення на 1/2 пікселя в X і Y, і знову повертаєтесь до пунктів, якщо вам все-таки потрібно мати точки.

EDIT: для складних правил прийняття рішень ви можете конвертувати кожне з полів, які вам потрібні як новий діапазон растрових, потім ви робите чотири копії цих діапазонів і зміщуєте растр у чотирьох напрямках на 1/2 пікселя (+50, - 50), (+ 50, + 50), (-50, -50) і (-50, + 50). Тоді ви можете використовувати звичайну алгебру карти


Дякую, я насправді продумав це рішення, але не впевнений, чи / як я можу реалізувати обчислення нового значення, якщо у растровому форматі. Поясню: для кожної нової точки (або нової растрової комірки) мені потрібно обчислити її значення як таке: я беру значення кожного з його сусідів. Кожне з цих значень має ймовірність надати певне значення новій точці. Наприклад, якщо один сусід має значення 202, то він дасть значення 3 (з вагою 1) або значення 11 (з вагою 5). Потім ми підводимо підсумки для всіх 4 сусідів і знаходимо нову цінність ... Не впевнений, чи це дуже ясно ...
Стефан Генріод

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

для вашої зваженої суми вам знадобляться лише два растри: один, де ви перепробовуєте добуток ваг і значень, другий, де ви перепробовуєте лише ваги. Якщо ділити перше на друге, ви отримаєте свою зважену суму.
radouxju

1
@ StéphaneHenriod - як пропозиція, ви можете розглянути питання про редагування питання, щоб додати ці додаткові характеристики. З огляду на початкове запитання, я думаю, що ця відповідь має багато сенсу, але з цією новою інформацією відповідь Барбароси виглядає добре.
nicksan

2

Дякую всім за допомогу!

Нарешті я знайшов дуже непітонічний спосіб вирішити цю проблему ... Що насправді забирало найбільше обчислювального часу, це знайти 4 сусіди кожної точки. Замість того, щоб використовувати атрибути X і Y (або з курсором аркпії, або в іншій структурі даних, наприклад, пітіонський дигітарій), я в кінцевому підсумку використовував інструмент ArcGIS Створення біля таблиці . Я припускаю, що цим скористаються просторові індекси, а ефективність, очевидно, набагато вища, без того, що мені доведеться сам реалізовувати індекс.


0

Проблема з курсорами полягає в тому, що ви можете проїхати їх лише одним способом і не можете повернутися назад. Хоча це і не рекомендується, ви можете заселити феатури до структури, якщо плануєте їх переглянути.

Якщо ви змогли обробити свої функції в одному циклі, пропоную ввімкнути переробку. Це параметр функції пошукового функціонального класу, який дозволяє python повторно використовувати пам'ять, виділену за старими функціями, і набагато швидше пересуває функції курсору. Ви можете обробити сітку на 80% швидше.

Проблема полягає в тому, що ви не можете ввімкнути переробку, якщо плануєте зберігати отримані функції з курсору.


Я хочу вивчити цю тему "переробляти курсор", але не можу знайти жодної документації довідки ESRI. У вас є посилання? У курсору пошуку немає параметра переробки. У Select_by_Attribute немає такого параметра. Я нічого не бачу в ENV.
klewis

Я написав статтю назад назад husseinnasser.com/2009/08/when-to-use-recycling-cursor.html?m=1
hnasr

1
Я не думаю, що «повторне використання курсорів» доступне через ArcPy, лише з ядром Arcobjects.
klewis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.