Maneiras de acelerar scripts Python em execução como ferramentas do ArcGIS [closed]

31

Esta é uma pergunta bastante geral. Só estou pensando em quais dicas e truques os programadores de GIS usaram para acelerar os scripts arqueados que você importa na caixa de ferramentas e executa.

Eu trabalho quase todos os dias escrevendo pequenos scripts para ajudar usuários não GIS no meu escritório a processar dados GIS. Descobri que o processamento do ArcGIS 10.0 em geral é mais lento que o 9.3.1 e às vezes fica ainda mais lento ao executar um script python.

Vou listar um exemplo específico de um script que leva mais de 24 horas para ser executado. É um loop que tabula a área de uma varredura em um buffer para cada forma no buffer. O buffer tem cerca de 7000 formas. Não acredito que deva durar tanto tempo. UMA

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

Antes que alguém diga, eu executei a área tabular em todo o buffer, mas produz erros se executado em mais de um registro. É uma ferramenta defeituosa, mas eu tenho que usá-la.

De qualquer forma, se alguém tiver alguma idéia de como otimizar ou acelerar esse script, seria muito apreciado. Caso contrário, você tem algum truque de aceleração para python, quando usado no ArcGIS?

Cody Brown
fonte

Respostas:

26

Algumas sugestões potenciais para ajudar a acelerar seu processo são:

  1. Selecionar Camada por atributo pode estar em um script somente em Python, sem abrir o ArcGIS Desktop. Você precisa converter sua referência "buff" de uma referência baseada em arquivo em uma referência "camada ArcGIS", na qual o ArcGIS pode processar consultas de seleção. Use arcpy.MakeFeatureLayer_management ("buff", "buff_lyr") acima do loop "while" e altere suas referências abaixo do loop while para usar "buff_lyr".

  2. Processe o máximo possível de suas operações de GP usando o espaço de trabalho in_memory possível ... Use arcpy.CopyFeatures_management (shapefile, "in_memory \ memFeatureClass") para mover sua fonte para a memória. Isso só funciona bem se você tiver RAM suficiente para ler todas as classes de recursos necessárias na memória. Cuidado, no entanto, que existem algumas operações de GP que não podem ser executadas usando o espaço de trabalho in_memory (por exemplo: a ferramenta Projeto).

No artigo de ajuda on-line do ArcGIS 9.3 " Dados intermediários e espaço de trabalho inicial " (observe, esse idioma foi removido da ajuda 10.0 e 10.1):

NOTA: Somente tabelas e classes de recursos (pontos, linhas, polígonos) podem ser gravadas no espaço de trabalho in_memory. O espaço de trabalho in_memory não suporta elementos de banco de dados geográficos estendidos, como subtipos, domínios, representações, topologias, redes geométricas e conjuntos de dados de rede. Somente recursos e tabelas simples podem ser gravados.

No artigo de ajuda on-line do ArcGIS 10.1 " Usando a área de trabalho na memória ":

As seguintes considerações devem ser feitas ao decidir gravar a saída no espaço de trabalho na memória:

  • Os dados gravados no espaço de trabalho na memória são temporários e serão excluídos quando o aplicativo for fechado.
  • Tabelas, classes de recursos e rasters podem ser gravadas no espaço de trabalho na memória.
  • O espaço de trabalho na memória não suporta elementos de geodatabase estendidos, como subtipos, domínios, representações, topologias, redes geométricas e conjuntos de dados de rede.
  • Conjuntos de dados ou pastas de recursos não podem ser criados no espaço de trabalho na memória.
RyanDalton
fonte
11
Isso é fantástico! Estive procurando uma maneira de usar seleções fora do ArcMap, mas até agora não obtive sucesso. Em termos desse problema, ele realmente reduziu meu tempo por linha para cerca de 13 segundos a partir de 20 segundos. Mas, eu fiz outro trabalho rápido e fiz o MakeFeatureLayer dentro do loop e ele caiu para 9 segundos. Eu fiz isso criando um recurso de cada forma do que tabulando a partir da camada de recurso. Eu ainda gostaria de descer ainda mais, se possível, mas já é um processo muito mais rápido!
Cody Brown
Conforme mencionado no item 2, use o CopyFeatures para fazer uma cópia dos dados de origem in_memory e, em seguida, crie seu feature_layer na fonte in_memory. Embora a cópia inicial na memória possa adicionar alguns segundos antes, você pode achar que o processamento das funções de cópia + tabulate_areas tem um tempo total de processamento mais rápido que o modelo atual.
RyanDalton
Eu tentei isso também e parece que essa solução tornaria o processo de loop mais rápido, mas isso não acontece. Criar a camada de recurso no loop resulta em cerca de 8 a 10 segundos por loop, enquanto cria a camada de recurso antes do loop resulta em 11 a 14 segundos por loop. Não sei ao certo por que, já que sua solução parece processar mais rápido. Eu tenho 8 GB de RAM, então duvido que esse seja o problema.
Cody Brown
Copiar também os recursos para in_memory antes do loop e, em seguida, ainda criar a camada de recursos no loop resulta em um desempenho um pouco mais rápido. Permanece praticamente 8 segundos por linha para cada loop. Que vai cair o tempo total do processo de 26 horas para 22.
Cody Brown
Depois de adicionar suas idéias, meu script melhorou dramaticamente. Muito obrigado pela sua ajuda e por todos!
Cody Brown
28

Técnicas gerais de otimização de python podem economizar uma quantidade substancial de tempo.

Uma técnica realmente boa para saber onde estão os atrasos no seu script é usar o módulo cProfile embutido:

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

Testar usando uma pequena amostra de dados permitirá identificar quais chamadas de função estão demorando mais tempo.

Ponteiros gerais para código python mais rápido:

  • Geralmente, as compreensões de lista são mais rápidas que o loop
  • Os geradores produzem um item de cada vez, em vez de produzir a lista inteira de uma só vez
  • Use xrange em vez do intervalo no python 2 (não é necessário no 3)
  • Sets pode sair listas pré-forma quando se trata de determinar se um item está presente no conjunto, mas são geralmente mais lento do que listas quando se trata de iteração sobre seu conteúdo Fonte
  • Chamadas de função pode ser caro para o desempenho Fonte
  • Mais dicas e detalhes, consulte aqui Dicas de desempenho do Python e aqui 10 Dicas e problemas de otimização do Python

Com relação ao seu script, não posso comentar sobre os aspectos do ArcPy, pois não tenho o Arc instalado neste computador, mas você pode tentar usar um loop for em vez de um while while para ver se isso melhora alguma coisa. Também x = x + 1 pode ser escrito como 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
James Milner
fonte
11
Usei os dois links que você deixou na sua última bala e foi capaz de realmente ajudar meu script com algumas correções rápidas!
Cody Brown
Se eu pudesse conceder duas respostas corretas, eu o faria. Enquanto sua resposta realmente ofereceu muitas idéias sobre como acelerar o python, o @RyanDalton ofereceu as que tiveram mais impacto. Muito obrigado!
Cody Brown
13

Verifique se você está gravando na unidade interna do computador. Alcançar a rede quando não é necessário pode realmente atrasar o processamento. Pode ser ainda mais rápido copiar os dados como a primeira etapa do processo para manter as leituras e gravações subsequentes o mais rápido possível

Executar o script completamente fora do ArcMap pode ser muito mais rápido. Se um mapa não for necessário durante o processamento, não use o ArcMap.

mhoran_psprep
fonte
Descobri que a execução de um script dentro de um modelo do ArcCatalog (por si só dentro de uma Calculate Valuecaixa de diálogo) será processada mais rapidamente do que a execução do mesmo script na janela do ArcPy no ArcMap. Isso é apenas uma observação anedótica.
Cindy Jayakumar
11
Acredito que preciso de um mapa para o Tabulate funcionar corretamente, mas vou tentar isso. Se funcionar fora do ArcMap, aposto que iria acelerar. Também já estou executando o disco local, que já dobrou a velocidade do script.
Cody Brown
Infelizmente, o Select não funciona fora do ArcMap e é necessário porque eu preciso fazer a tabulação de forma por forma.
Cody Brown
3
@ CodyBrown- Você está incorreto sobre o Select não funcionar fora de uma sessão do ArcMap. Veja minha resposta sobre o uso da ferramenta MakeFeatureLayer.
RyanDalton
Ryan está certo. Quando a ferramenta de seleção é usada sozinha, ela cria uma visualização de tabela dos dados espaciais ou da tabela. Ao usá-lo no ModelBuilde ou em um script, você deve criar uma exibição e, no seu caso, criá-la usando a ferramenta MakeFeatureLayer.
Dchaboya
6

Isso pode não responder à sua pergunta sobre a execução de ferramentas ArcPy no ArcMap, mas quando eu preciso fazer algum processamento de carne com ferramentas de geoprocessamento e Python, eu tendem a executá-lo fora do sistema GIS usando o IDE PyScripter . Eu descobri que corre mais rápido. Também empreguei um RAMDISK para pequenos conjuntos de dados de saída temporária (um pouco como o espaço de trabalho in_memory )

Bem, elas são minhas principais dicas! :)

Hornbydd
fonte
2
Para confundir essa resposta de alguma forma, ao executar scripts dos IDEs do Python, muitos injetam uma função traceback para ajudar na observação de variáveis ​​e outras diversas ajudas na depuração. Essa função pode desacelerar bastante os scripts se ela fizer muito quando é chamada TODO O TEMPO, e às vezes isso é instalado implicitamente sem a intervenção do usuário. Houve um caso patológico particular que observei em que um script Python executado no ArcMap foi executado em 4 minutos, enquanto o mesmo script do Wing IDE levou 3 horas. Assim que foi executado a partir do Python.exe sem o Wing, voltou ao território de tempo de execução de aproximadamente 2-3 minutos.
Jason Scheirer
11
Eu estava com dor de cabeça para ajustar meus scripts no ArMap, às vezes não consigo completamente, até que virei para o Pyscripter, ele pode reduzir o tempo de execução em comparação com o Arcmap, sem usar nenhuma dica de otimização.
Geogeek
@JasonScheirer, você encontrou o ajuste no Wing para desativar isso? Tenho certeza que existe um.
Curtis Preço
5

Tente comentar arcpy.SetProgressorLabel e veja quanto você acelera. Descobri que qualquer saída de tela, voltando ao DOS, diminui drasticamente o tempo de processamento. Se você realmente precisa ver essa saída, tente mostrá-la a cada enésimo laço.

user30749
fonte
4

Certifique-se de remover as import xxxxlinhas que não estão sendo usadas.

(ou seja, se você ainda não estiver usando nenhuma função matemática import Math, isso levará algum tempo a partir do carregamento do script)

Embora isso não tenha um grande impacto em scripts únicos executados (como o seu), afetará todos os scripts executados com frequência e repetição.

nagytech
fonte
7
Duvido que qualquer módulo Python padrão leve mais de um milésimo do tempo que o módulo arcpy leva para inicializar.
precisa saber é o seguinte
11
@ blah238 import Mathfoi provavelmente um mau exemplo. Algumas das maiores bibliotecas do ArcPy, no entanto, levam uma quantidade considerável de tempo para serem carregadas.
Nagytech
11
este barbas ainda fora apenas alguns segundos (no máximo!), não horas
Mike T
11
@MikeToews Para scripts que são executados com frequência e repetidamente, alguns segundos se acumulam ao longo de alguns dias / semanas etc. Embora isso não resolva o problema principal do OP, ele pediu dicas gerais.
Nagytech