У меня есть довольно большой класс точечных объектов в файловой базе геоданных (~ 4 000 000 записей). Это регулярная сетка точек с разрешением 100 м.
Мне нужно выполнить своего рода обобщение на этом слое. Для этого я создаю новую сетку, где каждая точка находится в середине 4 «старых» точек:
* * * *
o o o
* * * *
o o o
* * * *
[*] = точка исходной сетки - [o] = точка новой сетки
Значение атрибута каждой новой точки рассчитывается на основе взвешенных значений ее 4-х соседей в старой сетке. Таким образом, я зацикливаюсь на всех точках моей новой сетки и для каждой из них я зацикливаюсь на всех точках моей старой сетки, чтобы найти соседей (сравнивая значения X и Y в таблице атрибутов). Как только 4 соседа были найдены, мы выходим из цикла.
Здесь нет методологической сложности, но моя проблема в том, что, основываясь на моих первых тестах, этот сценарий будет длиться недели, чтобы завершиться ...
Видите ли вы возможность сделать его более эффективным? Несколько идей на моей голове:
- Индексируйте поля X и Y => Я сделал это, но не заметил значительного изменения производительности
- Сделайте пространственный запрос, чтобы найти соседей, а не на основе атрибутов. Это действительно поможет? Какая пространственная функция в ArcGIS должна выполнять эту работу? Я сомневаюсь, что, например, буферизация каждой новой точки окажется более эффективной
- Преобразуйте класс пространственных объектов в массив NumPy. Это поможет? До сих пор я мало работал с NumPy, и я не хотел бы углубляться в это, если кто-то не скажет мне, что это действительно может помочь сократить время обработки
- Что-нибудь еще?
источник
Ответы:
Что делать, если вы подали точки в массив numpy и использовали scipy cKDTree для поиска соседей. Используя эту технику, я обрабатываю облака точек LiDAR с большим количеством точек (> 20 миллионов) за несколько МИНУТ. Существует документация здесь для kdtree и здесь для Numpy преобразования. По сути, вы читаете x, y в массив и перебираете каждую точку массива, находя индексы точек на определенном расстоянии (окрестности) каждой точки. Вы можете использовать эти индексы для вычисления других атрибутов.
источник
Я с Barbarossa ... arcpy курсоры безумно хромают, поэтому я использую их только для того, чтобы пройти таблицу или класс пространственных объектов ровно один раз. Если я не могу выполнить работу за один цикл, я использую курсор, чтобы заполнить какую-то другую структуру данных и работать с ней.
Если вы не хотите суетиться с Numpy, просто создайте простой словарь Python, в котором вы используете свои координаты в качестве простого текстового ключа, и укажите атрибуты, необходимые для расчета, в список в качестве значения элемента словаря.
На втором этапе вы можете легко получить значения, необходимые для вычисления точки, просто получив их из своего словаря (что невероятно быстро из-за словарей hashindex элементов).
источник
Для обычной сетки гораздо эффективнее работать в растровом формате. Преобразовав свою первую сетку в растр, вы можете выполнить повторную выборку с тем же разрешением, используя билинейный интерполятор, но сместив ваше выходное изображение на 1/2 пикселя по осям X и Y, и снова вернитесь к точкам, если вам все еще нужны точки.
РЕДАКТИРОВАТЬ: для сложных правил принятия решений вы можете преобразовать каждое из необходимых полей в новую растровую полосу, затем сделать четыре копии этих полос и сдвинуть растр в 4 направлениях на 1/2 пикселя (+50, - 50), (+ 50, + 50), (-50, -50) и (-50, + 50). Тогда вы можете использовать регулярную карту алгебры
источник
Спасибо всем за вашу помощь!
В конце концов я нашел очень непитонический способ решения этой проблемы ... Что на самом деле занимало больше всего компьютерного времени, так это найти 4 соседей в каждой точке. Вместо того, чтобы использовать атрибуты X и Y (либо с дугообразным курсором, либо внутри другой структуры данных, например, python ditionary), я в итоге использовал инструмент ArcGIS Generate near table . Я предполагаю, что это использует пространственные индексы, и производительность, очевидно, намного выше, без необходимости самому внедрять индекс.
источник
Проблема с курсорами заключается в том, что вы можете перемещаться по ним только одним способом и не можете вернуться назад. Хотя это и не рекомендуется, вы можете заполнить феодоры структурой, если вы планируете вернуться к ним.
Если вы смогли обработать свои функции за один цикл, я предлагаю включить утилизацию. Это параметр в вашей функции поиска классов объектов, который позволяет Python повторно использовать память, выделенную старыми объектами, и значительно ускоряет обход объектов в курсоре. Вы можете обработать свою сетку на 80% быстрее.
Проблема в том, что вы не можете включить утилизацию, если планируете сохранять полученные функции из курсора.
источник