Aumentando a velocidade dos scripts Python usando o arcpy

8

Atualização 4/11/2014

Parece que o script estava sendo desligado na ferramenta Excluir Recursos, então mudei para Truncar Tabela, conforme sugerido na resposta abaixo. Também removi as variáveis ​​não utilizadas da ferramenta de acréscimo.

Atualização 4/10/2014

Eu executei esse script no computador do meu colega de trabalho (a máquina dele tem mais memória E contém ArcGIS 10.0 / Python26) e ele foi executado rapidamente. Viva! Quando meu suporte técnico encontrar o CD do ArcGIS 10.0, instalarei e testarei para ver se isso melhora a velocidade da minha máquina. Para deixar claro, estamos executando o mesmo script, nossa unidade de rede e conexão com o banco de dados são mapeadas de forma idêntica e as instruções de impressão são as mesmas. Vou postar uma atualização aqui assim que isso acontecer.

Terminar atualizações

Preciso aumentar a velocidade de alguns scripts Python que executam atualizações em um banco de dados Oracle. Eu tive esses scripts Python executando bem por mais de um ano, por meio de tarefas agendadas e arquivos em lote para iniciar os scripts. Na semana passada, mudei de um XP para uma máquina com Windows 7 e ArcGIS 10.0 -> 10.1. Desde então, os scripts tornaram-se terrivelmente lentos. Se eu executar esse script usando uma classe de recurso pequena (contendo ~ 20 recursos), ele será executado em 30 segundos. Se eu usar uma classe de recurso médio (~ 80.000 registros), ela será executada em 15 minutos. A classe de recurso que eu realmente preciso transferir rapidamente contém cerca de 1.000.000 de registros - o script só vai até a instrução print para verificar se os arquivos existem (se a instrução no código abaixo). Esse processo levaria apenas 35 minutos para ser concluído na minha máquina XP / ArcGIS 10.0.

Abaixo está o código simplificado com o qual tenho testado. Alguém tem sugestões sobre o que posso fazer para aumentar a velocidade? Obrigado, Patty

import arcpy, os, sys
from arcpy import env
arcpy.env.overwriteOutput = True
from datetime import datetime
import smtplib
import string
import urllib

#Define variables
inWorkspace = "O:/LANDING_PAD/BOE/example.gdb" 
lpFeatures = inWorkspace + os.sep + "fc1"
outWorkspace =  "Database Connections\\THIS.sde"
arcpy.env.workspace = outWorkspace
workspace = ""
copyFC = outWorkspace + os.sep + "SDE.fc1_1" #The feature class the script will update via delete and append
schema_type = "NO_TEST"
fieldMappings = ""
subtype = ""
t = datetime.now()
print "This script began at: " + str(t)

if arcpy.Exists(lpFeatures) is True and arcpy.Exists(copyFC) is True:
    print "Both files exist. Beginning delete..."
    arcpy.DeleteFeatures_management(copyFC) #(copyFC)

    print "ALL DONE DELETING!"

    arcpy.Append_management(lpFeatures, copyFC, schema_type, fieldMappings, subtype) #Append data from landing pad to db
    print "ALL DONE APPENDING!"
    record_count = arcpy.GetCount_management(lpFeatures)
    print record_count
    r = datetime.now()
    print "This script ended at: " + str(r)
Patty Jula
fonte
1
Não usei o arcpy, mas escrevi alguns Python e muitos sistemas paralelos em C #. É possível que você possa dividir seu trabalho em pedaços menores e trabalhar sobre eles em paralelo? Envie vários processos Python ou tente usar o encadeamento. Pode ficar confuso, especialmente se o arcpy não for seguro para threads, mas pode valer a pena quando você tiver muito o que fazer! Pode ser útil perguntar também no Stack Overflow.
jocull
A lentidão é porque você está excluindo todos os recursos individuais e anexando à classe de recursos esvaziados. Existe algum motivo para você não poder excluir toda a classe de recurso Delete_management()e recriá-la com CopyFeatures_management()ou FeatureClassToFeatureClass_conversion()?
Nfeterson
2
Você já fez alguma criação de perfil ( docs.python.org/2/library/profile.html ) para determinar onde a maior parte do seu processamento está ocorrendo? Seria interessante ver seus resultados.
Aaron
1
@ jocull sim, eu pensei em montar algo que usa multiprocessamento, mas fiquei um pouco preso em como os scripts eram tão rápidos no meu XP / ArcGIS 10.0 e lentos no Windows 7 / 10.1. Aaron, sim, seria legal ver onde o processamento está ocorrendo. Vou analisar o perfil do script. Obrigado, patty
Patty Jula
Postei uma atualização acima. Basicamente, os scripts são executados rapidamente na máquina do meu colega de trabalho, o que é bom.
quer

Respostas:

7

Eu queria comentar primeiro, mas depois parecia mais apropriado envolvê-lo como resposta (mesmo que incompleto).

Executei o seu código na minha máquina (laptop de hardware com SSD) anexando uma classe de recurso de banco de dados geográficos a uma classe de recursos de banco de dados geográfico do SQL Server na mesma máquina, o que me levou em torno de 13 min. Não sei ao certo por que a velocidade de execução difere tanto em seu ambiente (10.0 >> 10.1), mas você pediu sugestões sobre o que pode ser feito para aumentar a velocidade , portanto, aqui estão algumas idéias que podem aumentar a velocidade de executar o script.

1) Executo o script a partir da linha de comando, que é equivalente a executar um arquivo .bat (executo o script no formato de 64 bits, tenho o ArcGISx6410.2 Python de 64 bits instalado).

c:\Python27\ArcGISx6410.2\python.exe c:\scripts\appendfc.py

Pela minha experiência, geralmente é mais rápido executar a versão de 64 bits do Python para executar operações GP longas e pesadas, como o Append. Então você quer ter certeza de executar esta versão do Python ao executar o script.

2) Eu não recomendaria o uso arcpy.DeleteFeatures_management; é muito mais lento do que executar Truncate Table, pois o último não usa transações de banco de dados, o que melhora o desempenho em relação à exclusão linha por linha.

Você mencionou que o script vai apenas até a instrução print para verificar se os arquivos existem (se a instrução estiver no código) . Há uma boa chance de ele continuar excluindo linha por linha, o que pode ser um processo muito lento quando você acessa uma tabela em um banco de dados Oracle (ou realmente qualquer DBMS) remoto. Tente executar o script com Truncate Table, mas sem Anexar primeiro, apenas para ver a diferença de desempenho no estágio de exclusão.

3) Você parece estar usando "Database Connections\\THIS.sde"o código. No entanto, é melhor consultar o próprio arquivo de conexão (arquivo .sde) com o sistema de arquivos ou o caminho UNC, não a pasta "Conexões de banco de dados" da janela Catálogo. Você pode acessar o arquivo .sde criado em C:\Users\%user%\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog. Você pode mover esse arquivo .sde conforme necessário e colocar na pasta à qual o script Python terá acesso.

4) Na arcpy.Append_managementfunção, você usa alguns parâmetros vazios. Em teoria, isso não deve fazer nenhuma diferença, mas eu sugeriria executar a função sem especificar esses parâmetros apenas porque você não precisa deles. Você nunca sabe o que está acontecendo nos bastidores e se essas cadeias vazias são avaliadas em algum momento e se isso pode afetar o desempenho. Basta seguir arcpy.Append_management(lpFeatures, copyFC, schema_type)e não especificar parâmetros para os quais você não fornece nenhum valor.

5) Desencorajo o uso os.sepao criar um caminho para uma classe de recurso. Use os.path.join(geodatabase,featureclassname)para isso em vez disso. É apenas mais limpo e mais legível.

Você pode adicionar mais detalhes à pergunta depois de tentar as coisas acima e fazer alguns testes e revisão de código.

Algumas boas perguntas para ler para obter mais informações sobre como acelerar os scripts Python no ArcGIS:

Desempenho do ArcGISScripting e grandes conjuntos de dados espaciais

Geoprocessamento em segundo plano (64 bits)

A ferramenta Arcgis CopyFeatures é extremamente lenta ao exportar para SDE

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

Considerações de geoprocessamento para dados do ArcSDE

Alex Tereshenkov
fonte
Muito obrigado, você salvou minha sexta-feira. Eu queria acrescentar que sim, posso chamar um banco de dados em um arquivo em lotes chamado "Database Connections\\THIS.sde". Talvez seja porque o arquivo em lote está apenas iniciando os scripts Python que usam essa variável? Não posso ter um banco de dados chamado, o THIS database.sdeque é estranho para mim, pois existe um espaço Database Connections. Obrigado novamente,
Patty Jula
Fico feliz que foi útil. 1. Como está o desempenho agora? 2. Interessante com "Conexões com o Banco de Dados". Eu tinha tanta certeza de que você não pode se referir a esta "pasta" na janela do Catálogo quando não está executando o script da GUI do ArcGIS Desktop, mas estava errado. Atualizei minha resposta para refletir isso. 3. Você pode ter o arquivo de conexão "this database.sde", é possível usar espaços. Mas você não pode ter um banco de dados no Oracle com espaços com, exatamente como o DBMS funciona.
Alex Tereshenkov
O desempenho está melhorado agora. O processo para executar a classe de recursos com um milhão de registros (de pontos de endereço) é executado na máquina Windows 7 / ArcGIS 10.1 agora (antes de congelar na ferramenta de exclusão de recursos). Demora 3 horas para executar todo esse processo. Esse processo levou 50 minutos na minha máquina XP / 10.0. É a este link que você estava se referindo com o ponto 1 na sua resposta?
Patty Jula
@ PattyJula, certo, é esse aqui. Você não precisa instalar / usar o software de processamento em segundo plano instalado na parte superior. Você só precisa usar o sabor de Python de 64 bits ao executar seu script.
Alex Tereshenkov
Obrigado pela sugestão. Instalei o Python de 64 bits e um cliente Oracle de 64 bits. Meus scripts ainda não estão sendo executados na velocidade em que foram executados na minha configuração do XP / ArcGIS 10.0. Vou agendar uma tarefa para executar os arquivos em lotes e os scripts Python hoje à noite. Se a velocidade não melhorar, talvez seja necessário configurar outra máquina executando o ArcGIS 10.0.
Patty Jula
1

Espero que este exemplo também ajude a responder à pergunta e esteja em um software mais recente. Ele se baseia nas respostas e comentários mencionados acima.

Configuração:

  1. Windows 7
  2. SQL Server 2012 R2
  3. ArcGIS 10.2.2 (Servidor e Desktop)

A carga precisava ser noturna. Foram ~ 9300 registros e 234 atributos.

O modelo original estava abaixo e foi feito tudo no SQL Server 2012 R2 / SDE (7 minutos via ArcCatalog e 3 horas com python):

  1. Excluir linhas da classe de recurso no SDE
  2. Criar camada de evento XY da tabela no SQL Server
  3. Anexar à classe de recurso no SDE

Como eu a alterei (10 segundos via ArcCatalog e 10 segundos via python):

  1. Ferramenta de linhas de exclusão substituída pela ferramenta Truncar para a classe GIS Feature no SDE
  2. Exporte a tabela SQL para um FGDB na unidade C local
  3. Criar camada de eventos XY na memória local
  4. Classe de recurso a Classe de recurso no FGDB na unidade C local
  5. ENTÃO Anexe a classe Feature FGDB ao SDE
  6. Observe que meu banco de dados do SQL Server está na mesma unidade C do meu FGDB. Pode ficar um pouco mais lento em uma rede, mas ainda assim provavelmente não nas 3 horas que eu estava vendo.

O que ajudou um pouco no modelo original foi substituir as fontes de dados conforme o # 3 recomendado acima. Ele cortou 30 segundos ao executar no ArcCatalog. Com python, ele cortou cerca de 20 minutos. Portanto, é uma variável em velocidade, mas não é a variável mais valiosa a ser abordada no meu caso. Parece que, de acordo com a maioria dos blogs, o SQL Server simplesmente não gosta de carregar muito dados "da memória" (por exemplo, criar uma camada de eventos xy). O SQL / SDE parece preferir um objeto real para carregar. Isso explica por que minhas outras cargas, da mesma maneira, levam 1 minuto, mas esses são apenas 1000 registros com 15 atributos, por isso nunca questionei a eficiência de meus modelos até que essa carga precisasse ser executada todas as noites. Como mencionado, essa carga é de 9000 registros com 236 atributos.

Dylan Kennard
fonte
0

O problema com o desempenho entre 10.0 e 10.1 é que algo nas bibliotecas SDE foi alterado na área de trabalho. Costumávamos postar 1.000.000 por noite e levávamos apenas 45 minutos, após uma atualização de software que levava quase 24 horas. Obviamente, não há problema com os dados e apenas o software foi alterado.

Verifique a versão do geodatabase para garantir que ela corresponda à versão do cliente que está executando o arcpy. Relatamos isso à ESRI sem resposta ou reconhecimento de um bug. É bastante óbvio e o problema começou após o 10.0 SP1.

Além disso, outro teste de copiar / colar é mais rápido que um anexo. Tente fazer isso nas versões 10.0 e 10.1 e o desempenho deve ser semelhante. Isso prova que há algum tipo de bug nas versões anteriores ao anexar geometrias.

user63844
fonte