Augmentation de la vitesse des scripts Python en utilisant arcpy

8

Mise à jour 4/11/2014

Il semble que le script se soit bloqué sur l'outil Supprimer les fonctionnalités, j'ai donc basculé vers Tronquer la table, comme suggéré dans la réponse ci-dessous. J'ai également supprimé les variables inutilisées de l'outil d'ajout.

Mise à jour 4/10/2014

J'ai exécuté ce script sur l'ordinateur de mon collègue (sa machine a plus de mémoire ET contient ArcGIS 10.0 / Python26) et il s'est exécuté rapidement. Hourra! Une fois que mon support technique aura trouvé le CD d'ArcGIS 10.0, j'installerai et testerai pour voir si cela améliore la vitesse sur ma machine. Pour être clair, nous exécutons le même script, notre lecteur réseau et notre connexion à la base de données sont mappés de manière identique et les instructions d'impression sont les mêmes. Je publierai une mise à jour ici une fois que cela se produira.

Mettre fin aux mises à jour

J'ai besoin d'augmenter la vitesse de certains scripts Python qui effectuent des mises à jour sur une base de données Oracle. J'ai eu ces scripts Python fonctionnant bien pendant un an +, via des tâches planifiées et des fichiers batch pour lancer les scripts. La semaine dernière, je suis passé d'un XP à une machine Windows 7 et ArcGIS 10.0 -> 10.1. Depuis lors, les scripts sont devenus terriblement lents. Si j'exécute ce script à l'aide d'une petite classe d'entités (contenant environ 20 fonctions), il s'exécute en 30 secondes. Si j'utilise une classe d'entités moyenne (~ 80 000 enregistrements), elle s'exécute en 15 minutes. La classe d'entités que j'ai vraiment besoin de pouvoir transférer rapidement contient environ 1 000 000 d'enregistrements - le script va jusqu'à l'instruction print pour vérifier si les fichiers existent (si instruction dans le code ci-dessous). Ce processus ne prendrait que 35 minutes pour se terminer sur ma machine XP / ArcGIS 10.0.

Vous trouverez ci-dessous le code simplifié avec lequel j'ai testé. Quelqu'un a-t-il des suggestions sur ce que je peux faire pour augmenter la vitesse? Merci, 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
la source
1
Je n'ai pas utilisé arcpy, mais j'ai écrit du Python et beaucoup de systèmes parallèles en C #. Est-il possible que vous puissiez diviser votre travail en plus petits morceaux et les travailler en parallèle? Soit répartissez plusieurs processus Python, soit essayez d'utiliser le filetage. Cela pourrait devenir compliqué, surtout si arcpy n'est pas compatible avec les threads, mais cela pourrait être payant lorsque vous avez beaucoup à faire! Il peut également être utile de poser des questions sur Stack Overflow.
jocull
La lenteur est due au fait que vous supprimez toutes les fonctionnalités individuelles et que vous les ajoutez à la classe d'entités vidée. Y a-t-il une raison pour laquelle vous ne pouvez pas supprimer la classe d'entités entière avec Delete_management(), puis la recréer avec CopyFeatures_management()ou FeatureClassToFeatureClass_conversion()?
nmpeterson
2
Avez-vous effectué un profilage ( docs.python.org/2/library/profile.html ) pour déterminer où se déroule l'essentiel de votre traitement? Il serait intéressant de voir vos résultats.
Aaron
1
@jocull oui, j'ai pensé à créer quelque chose qui utilise le multitraitement, mais j'étais un peu coincé sur la rapidité des scripts sur XP / ArcGIS 10.0 et sur Windows 7 / 10.1. Aaron, oui, ce serait cool de voir où le traitement a lieu. Je vais examiner le profilage du script. Merci, patty
Patty Jula
J'ai posté une mise à jour ci-dessus. Fondamentalement, les scripts s'exécutent rapidement sur la machine de mon collègue, ce qui est bien.
Patty Jula

Réponses:

7

J'ai voulu commenter d'abord, mais ensuite il a semblé plus approprié d'en faire une réponse (même si elle peut être incomplète).

J'ai exécuté votre code sur ma machine (ordinateur portable avec matériel SSD supérieur) en ajoutant une classe d'entités de géodatabase fichier à une classe d'entités de géodatabase SQL Server sur la même machine, ce qui m'a pris environ 13 minutes. Je ne peux pas vous dire avec certitude pourquoi la vitesse d'exécution diffère tellement dans votre environnement (10.0 >> 10.1), mais vous avez demandé des suggestions sur ce que vous pouvez faire pour augmenter la vitesse , alors voici quelques idées qui pourraient augmenter la vitesse d'exécuter le script.

1) J'exécute le script à partir de la ligne de commande, ce qui équivaut à exécuter un fichier .bat (j'exécute le script en version 64 bits, j'ai installé ArcGISx6410.2 64 bits Python).

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

D'après mon expérience, il est généralement plus rapide d'exécuter une version 64 bits de Python pour exécuter des opérations de GP longues et lourdes comme Append. Vous devez donc vous assurer que vous exécutez cette version de Python lors de l'exécution du script.

2) Je ne recommanderais pas d'utiliser arcpy.DeleteFeatures_management; il est beaucoup plus lent que d'exécuter Truncate Table car ce dernier n'utilise pas les transactions de base de données, ce qui améliore les performances par rapport à la suppression ligne par ligne.

Vous avez mentionné que le script va uniquement jusqu'à l'instruction print pour vérifier si les fichiers existent (si instruction dans le code) . Il y a de fortes chances qu'il continue de supprimer ligne par ligne ce qui peut être un processus très lent lorsque vous accédez à une table dans une base de données Oracle distante (ou vraiment n'importe quel SGBD). Essayez d'exécuter le script avec Truncate Table, mais sans ajout tout d'abord pour voir la différence de performances à l'étape de suppression.

3) Vous semblez utiliser "Database Connections\\THIS.sde"dans le code. Il est toutefois préférable de se référer au fichier de connexion lui-même (fichier .sde) avec le système de fichiers ou le chemin UNC, et non au dossier "Connexions à la base de données" de la fenêtre Catalogue. Vous pouvez accéder au fichier .sde créé à C:\Users\%user%\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog. Vous pouvez déplacer ce fichier .sde selon vos besoins et le placer dans le dossier auquel le script Python aura accès.

4) Dans la arcpy.Append_managementfonction, vous utilisez quelques paramètres vides. En théorie, cela ne devrait faire aucune différence, mais je suggérerais d'exécuter la fonction sans spécifier ces paramètres simplement parce que vous n'en avez pas besoin. Vous ne savez jamais ce qui se passe dans les coulisses et si ces chaînes vides sont évaluées à un moment donné et si cela peut avoir un impact sur les performances. Allez-y arcpy.Append_management(lpFeatures, copyFC, schema_type)et ne spécifiez pas de paramètres pour lesquels vous ne fournissez aucune valeur.

5) Je déconseille l'utilisation os.seplors de la création d'un chemin vers une classe d'entités. Utilisez os.path.join(geodatabase,featureclassname)pour cela à la place. Il est juste plus propre et plus lisible.

Vous pouvez ajouter plus de détails à la question après avoir essayé les choses ci-dessus et passé quelques tests et revue de code.

Quelques bonnes questions à lire pour obtenir plus d'informations sur la façon d'accélérer les scripts Python dans ArcGIS:

Performances d'ArcGISScripting et de grands ensembles de données spatiales

Géotraitement en arrière-plan (64 bits)

L'outil Arcgis CopyFeatures est extrêmement lent lors de l'exportation vers SDE

Moyens d'accélérer les scripts Python s'exécutant en tant qu'outils ArcGIS

Considérations de géotraitement pour les données ArcSDE

Alex Tereshenkov
la source
Merci beaucoup, vous avez sauvé mon vendredi. Je voulais ajouter que oui, je peux appeler une base de données dans un fichier batch nommé "Database Connections\\THIS.sde". Peut-être est-ce parce que le fichier batch ne fait que lancer les scripts Python qui utilisent cette variable? Je ne peux pas avoir de base de données nommée THIS database.sdequi m'est étrange car il y a un espace dedans Database Connections. Merci encore,
Patty Jula
Heureux que ce soit utile. 1. À quoi ressemble la performance maintenant? 2. Intéressant avec "Connexions à la base de données". J'étais tellement sûr que vous ne pouvez pas faire référence à ce "dossier" dans la fenêtre Catalogue lorsque vous n'exécutez pas le script à partir de l'interface graphique d'ArcGIS Desktop, mais je me trompais. J'ai mis à jour ma réponse pour refléter cela. 3. Vous pouvez avoir le fichier de connexion "this database.sde", les espaces sont OK à utiliser. Mais vous ne pouvez pas avoir une base de données dans Oracle avec des espaces avec juste comment fonctionne le SGBD.
Alex Tereshenkov
Les performances sont désormais améliorées. Le processus d'exécution de la classe d'entités millions d'enregistrements (de points d'adresses) s'exécute maintenant sur la machine Windows 7 / ArcGIS 10.1 (avant de se bloquer sur l'outil de suppression d'entités). Il faut 3 heures pour exécuter l'ensemble de ce processus. Ce processus a pris 50 minutes sur ma machine XP / 10.0. Est-ce ce lien auquel vous faisiez référence avec le point 1 de votre réponse?
Patty Jula
@PattyJula, à droite, c'est celui-ci. Vous n'avez pas besoin d'installer / d'utiliser un logiciel de traitement en arrière-plan installé par-dessus. Il vous suffit d'utiliser la version 64 bits de Python lors de l'exécution de votre script.
Alex Tereshenkov
Merci pour la suggestion. J'ai installé Python 64 bits plus un client Oracle 64 bits. Mes scripts ne fonctionnent toujours pas à la vitesse qu'ils ont exécutée avec ma configuration XP / ArcGIS 10.0. Je vais planifier une tâche pour exécuter les fichiers batch et les scripts Python ce soir, si la vitesse ne s'améliore pas, je devrai peut-être configurer une autre machine exécutant ArcGIS 10.0.
Patty Jula
1

J'espère que cet exemple aidera également à répondre à la question et concerne un logiciel plus récent. Il s'appuie sur les réponses et commentaires mentionnés ci-dessus.

Installer:

  1. Windows 7
  2. SQL Server 2012 R2
  3. ArcGIS 10.2.2 (serveur et bureau)

La charge devait être nocturne. C'était ~ 9300 enregistrements et 234 attributs.

Le modèle d'origine était ci-dessous et a été fait tout dans SQL Server 2012 R2 / SDE (7 minutes via ArcCatalog et 3 heures avec python):

  1. Supprimer des lignes de classe d'entités dans SDE
  2. Créer une couche d'événements XY à partir d'une table dans SQL Server
  3. Ajouter à la classe d'entités dans SDE

Comment je l'ai modifié (10 secondes via ArcCatalog & 10 secondes via python): •

  1. Outil de suppression de lignes remplacé par l'outil Tronquer pour la classe d'entités SIG dans SDE
  2. Exporter la table SQL vers un FGDB sur le lecteur C local
  3. Créer une couche d'événements XY sur la mémoire locale
  4. Classe d'entités à classe d'entités dans FGDB sur le lecteur C local
  5. PUIS ajouter la classe d'entités FGDB dans SDE
  6. Notez que ma base de données SQL Server se trouve sur le même lecteur C que mon FGDB. Cela peut ralentir un peu sur un réseau, mais probablement pas les 3 heures que je voyais.

Ce qui a aidé un peu sur le modèle d'origine a été de remplacer les sources de données conformément au point 3 recommandé ci-dessus. Il s'est réduit de 30 secondes lors de l'exécution dans ArcCatalog. Avec du python, il s'est rasé environ 20 minutes. C'est donc une variable de vitesse mais ce n'est pas la variable la plus précieuse à aborder dans mon cas. Il semble que, selon la plupart des blogs, SQL Server n'aime tout simplement pas le chargement de données lourdes «à partir de la mémoire» (c'est-à-dire créer une couche d'événements xy). SQL / SDE semble préférer un objet réel à charger. Cela explique pourquoi mes autres chargements que je fais de la même manière prennent 1 minute, mais ce ne sont que 1000 enregistrements avec 15 attributs donc je n'ai jamais remis en question l'efficacité de mes modèles jusqu'à ce que ce chargement doive être fait tous les soirs. Comme mentionné, cette charge est de 9 000 enregistrements avec 236 attributs.

Dylan Kennard
la source
0

Le problème avec les performances entre 10.0 et 10.1 est quelque chose dans les bibliothèques SDE a été modifié sur le bureau. Nous publions 1 000 000 tous les soirs et ne prenions que 45 minutes, après une mise à jour logicielle, cela prenait presque 24 heures. Évidemment, il n'y a pas de problème avec les données et seul le logiciel a été changé.

Vérifiez la version de la géodatabase pour vous assurer qu'elle correspond à la version du client exécutant arcpy. Nous l'avons signalé à ESRI sans réponse ni reconnaissance d'un bogue. C'est assez évident et le problème a commencé après 10.0 SP1.

Un autre test, un copier / coller est plus rapide qu'un ajout, essayez ceci à partir de 10.0 et 10.1 et les performances devraient être similaires. Cela prouve qu'il existe une sorte de bogue dans les versions précédentes lors de l'ajout de géométries.

user63844
la source