Использование рабочего стола arcgis 10.3.1 У меня есть скрипт, который использует курсор поиска для добавления значений в список, а затем использует min (), чтобы найти наименьшее целое число. Переменная затем используется в скрипте. Класс Feature содержит 200 000 строк, и выполнение сценария занимает очень много времени. Есть ли способ сделать это быстрее? На данный момент я думаю, что я бы просто сделал это вручную, а не написал сценарий, потому что это занимает много времени.
import arcpy
fc = arcpy.env.workspace = arcpy.GetParameterAsText(0)
Xfield = "XKoordInt"
cursor = arcpy.SearchCursor(fc)
ListVal = []
for row in cursor:
ListVal.append(row.getValue(Xfield))
value = min(ListVal)-20
print value
expression = "(!XKoordInt!-{0})/20".format(value)
arcpy.CalculateField_management (fc, "Matrix_Z" ,expression, "PYTHON")
arcpy.Statistics_analysis
? desktop.arcgis.com/en/arcmap/10.3/tools/analysis-toolbox/…min_val = min([i[0] for i in arcpy.da.SearchCursor(fc,Xfield)])
Ответы:
Я вижу несколько вещей, которые могут вызывать медленный сценарий. То, что, вероятно, очень медленно, это
arcpy.CalculateField_management()
функция. Вы должны использовать курсор, он будет на несколько величин быстрее. Кроме того, вы сказали, что используете ArcGIS Desktop 10.3.1, но используете старые курсоры в стиле ArcGIS 10.0, которые также намного медленнее.Операция min () даже в списке из 200K будет довольно быстрой. Вы можете убедиться в этом, запустив этот небольшой фрагмент; это происходит в мгновение ока:
Посмотрим, будет ли это быстрее:
РЕДАКТИРОВАТЬ:
Я провел несколько временных тестов, и, как я подозревал, полевой калькулятор занял почти вдвое больше времени, чем курсор нового стиля. Интересно, что курсор в старом стиле был в 3 раза медленнее, чем полевой калькулятор. Я создал 200 000 случайных точек и использовал те же имена полей.
Для определения времени каждой функции использовалась функция декоратора (это может быть связано с небольшими издержками при установке и отключении функций, поэтому, возможно, модуль timeit будет немного более точным для тестирования фрагментов).
Вот результаты:
И вот код, который я использовал (разбил все на отдельные функции, чтобы использовать
timeit
декоратор):И, наконец, это то, что было распечатано с моей консоли.
Редактировать 2: только что опубликовал несколько обновленных тестов, я обнаружил небольшой недостаток с моей
timeit
функцией.источник
"XKoordInt"
. Смотрите мое редактирование, все, что вам нужно сделать, это пропустить нули.range
. ArcGIS по-прежнему использует Python 2.7, поэтому возвращает alist
. Но в 3.xrange
есть свой особый вид объекта, который может иметь оптимизации. Был бы более надежный тестmin(list(range(200000)))
, который бы гарантировал, что вы работаете с простым списком. Также рассмотрите возможность использованияtimeit
модуля для тестирования производительности.Как указывает @crmackey, медленная часть, вероятно, связана с методом вычисления поля. В качестве альтернативы другим подходящим решениям и при условии, что вы используете базу геоданных для хранения ваших данных, вы можете использовать команду Упорядочить по sql для сортировки в порядке возрастания перед выполнением курсора обновления.
В этом случае предложение where удаляет пустые значения перед выполнением запроса, или вы можете использовать другой пример, который проверяет None перед обновлением.
источник
min()
. Я включу это в свои тесты скорости, чтобы показать прирост производительности.0.56
секунды, что не так сильно, как я ожидал.Вы также можете использовать Numpy в таких случаях, хотя это будет более интенсивно использовать память.
У вас все еще будет узкое место при загрузке данных в массив numpy, а затем снова в источник данных, но я обнаружил, что разница в производительности лучше (в пользу numpy) с большими источниками данных, особенно если вам нужно несколько статистика / расчеты .:
источник
Почему бы не отсортировать таблицу по возрастанию, а затем использовать курсор поиска, чтобы получить значение для первой строки? http://pro.arcgis.com/en/pro-app/tool-reference/data-management/sort.htm
источник
Я бы обернул
SearchCursor
в выражение генератора (то естьmin()
) для скорости и краткости. Затем включите минимальное значение из выражения генератора вda
типUpdateCursor
. Что-то вроде следующего:источник
SearchCursor
быть закрыты, когда вы закончите с этим?В вашем цикле у вас есть две ссылки на функции, которые переоцениваются для каждой итерации.
for row in cursor: ListVal.append(row.getValue(Xfield))
Должно быть быстрее (но немного сложнее) иметь ссылки вне цикла:
источник
append()
метода типаlist
данных. Я не думаю, что именно здесь происходит его узкое место, я бы поспорил, что функция вычисления поля является виновником. Это можно проверить, синхронизировав калькулятор поля с курсором нового стиля.