Suite

L'équation du calculateur de champ simple dans ArcGIS 10.2.1 ne fonctionne pas avec l'analyseur python

L'équation du calculateur de champ simple dans ArcGIS 10.2.1 ne fonctionne pas avec l'analyseur python


J'essaie de calculer un pourcentage dans un champ d'une table. clients et total_clients sont des champs d'entiers courts.

arcpy.AddField_management(tableSepSel2, "percent", "DOUBLE") arcpy.CalculateField_management(tableSepSel2, "percent", "!customers! / !total_customers!*100", "PYTHON_9.3")

Je ne reçois aucune erreur, mais toutes les valeurs du champ pourcentage sont nulles alors que la plupart d'entre elles ne devraient pas être nulles.

Si j'entre dans ArcMap et que j'utilise la calculatrice de champ avec l'analyseur Python, la même chose se produit. Cependant, lorsque je choisis l'analyseur VBScript dans ArcMap et que je refais le code à l'aide de crochets, cela fonctionne bien.


je devineles clientsettotal_clientssont des champs d'entiers et l'équation utilise des mathématiques d'entiers, ce qui donne le résultat arrondi (0 * 100) dans tous les cas, sauf lorsqueclients == total_clients(1 * 100).

Utilisez cette équation pour obtenir des calculs décimaux :

"float(!customers!) / float(!total_customers!) * 100"

Comment créer une zone de saisie avec Python ?

Je souhaite créer une zone de saisie à l'écran avec laquelle un utilisateur peut interagir.

L'utilisateur verrait une fenêtre avec un champ de saisie sur lequel il peut cliquer avec la souris. L'utilisateur peut saisir ou effacer du texte dans le champ, puis appuyer sur OK une fois qu'il a fini d'ajouter du texte. Enfin, mon programme stockerait ce texte pour une utilisation ultérieure.

Comment puis-je créer une zone de texte en Python permettant la saisie par l'utilisateur ?


9 réponses 9

Il semble que vous entriez une ligne vide après le corps de l'instruction if. Ceci indique au compilateur interactif que vous avez entièrement terminé avec le bloc, il n'attend donc aucun bloc elif / else. Essayez d'entrer le code exactement comme ceci, et appuyez uniquement sur Entrée une fois après chaque ligne :

Le problème est la ligne vide que vous tapez avant else ou elif . Faites attention à l'invite qui vous est donnée. S'il s'agit de >>> , Python attend le début d'une nouvelle instruction. Si c'est . , alors il s'attend à ce que vous continuiez une instruction précédente.

elif et sinon doit immédiatement suivre la fin du bloc if, ou Python supposera que le bloc s'est fermé sans eux.

Dans votre code, l'interpréteur termine le bloc if lors de l'indentation, donc elif et else ne lui sont pas associés. Ils sont donc compris comme des déclarations autonomes, ce qui n'a pas de sens.

En général, essayez de suivre les directives de style, qui incluent la suppression des espaces blancs excessifs.

Dans IDLE et le python interactif, vous avez entré deux CRLF consécutifs qui vous font sortir de l'instruction if. C'est le problème de IDLE ou python interactif. Tout ira bien lorsque vous utiliserez n'importe quel type d'éditeur, assurez-vous simplement que votre indentation est correcte.

Assurez-vous que votre identité est correcte. La syntaxe est correcte.

N'oubliez pas que par défaut, la valeur de retour de l'entrée sera une chaîne et non un entier. Vous ne pouvez pas comparer des chaînes avec des booléens comme <, >, =>, <= (sauf si vous comparez la longueur). Par conséquent, votre code devrait ressembler à ceci :

De plus, votre indentation est erronée. Le code ne fonctionnera pas. Je sais que vous utilisez python 3. quelque chose. J'utilise python 2.7.3, le code qui fonctionnera réellement pour ce que vous essayez d'accomplir est le suivant.

La seule différence, je dirais à python que ce nombre est une chaîne de caractères pour que le code fonctionne. Si non va penser est un entier. Lorsque quelqu'un exécute le code, il entre une chaîne et non un entier. Il existe de nombreuses façons de modifier ce code, mais c'est la solution simple que je voulais fournir. Il y a une autre façon à laquelle je ne peux pas penser sans transformer le 23 en chaîne. Ou vous pourriez mettre des guillemets sur "23" ou vous pourriez utiliser la fonction int() dans l'entrée. cela transformerait tout ce qu'ils entreraient et en entier un nombre.

Python peut générer la même erreur de 'syntaxe invalide' même si l'identifiant du bloc 'elif' ne correspond pas à l'identifiant du bloc 'if' (tabulations pour le premier, espaces pour le second ou vice versa).

l'indentation est importante en Python. Votre instruction if else doit se trouver dans la triple flèche (>>>), dans Mac python IDLE version 3.7.4, l'instruction elif n'est pas fournie avec une indentation correcte lorsque vous passez à la ligne suivante, vous devez vous déplacer vers la gauche pour éviter les erreurs de syntaxe.


Préconditionner le modèle d'élévation

Avant de commencer votre analyse, vous allez préconditionner un modèle altimétrique numérique (MNE) de Stowe, Vermont, afin de réduire la possibilité d'erreurs dans vos résultats. Certains DEM contiennent des puits, qui sont des zones de faible altitude entourées de valeurs d'altitude plus élevées. Les récepteurs peuvent se produire naturellement, mais sont plus souvent des erreurs de données dans un jeu de données raster DEM. Parce que l'eau n'a aucun moyen de s'écouler d'un évier, les éviers peuvent provoquer toutes sortes d'erreurs lors de l'analyse de la façon dont l'eau s'écoule vers une sortie. Avant de commencer votre analyse hydrologique du potentiel d'inondation à Stowe, vous allez identifier et supprimer les puits de vos données d'altitude.


5 réponses 5

Et SymPy ? Leur solveur ressemble à ce dont vous avez besoin. Jetez un œil à leur code source si vous souhaitez créer la bibliothèque vous-même…

Il y a deux manières d'aborder ce problème : numériquement et symboliquement.

Pour le résoudre numériquement, vous devez d'abord l'encoder en tant que fonction "exécutable" - coller une valeur, extraire une valeur. Par exemple,

Il est tout à fait possible d'analyser une chaîne pour créer automatiquement une telle fonction disons que vous analysez 2x + 6 dans une liste, [6, 2] (où l'index de la liste correspond à la puissance de x - donc 6*x^0 + 2* x^1). Puis:

Vous avez ensuite besoin d'une autre fonction qui branche à plusieurs reprises une valeur x dans votre fonction, examine la différence entre le résultat et ce qu'elle veut trouver, et ajuste sa valeur x pour (espérons-le) minimiser la différence.

Il y a beaucoup de problèmes potentiels ici - trouver une bonne valeur x de départ, en supposant que la fonction a réellement une solution (c'est-à-dire qu'il n'y a pas de réponses réelles à x^2 + 2 = 0), atteindre les limites de la précision de calcul, etc. Mais dans ce cas, la fonction de minimisation d'erreur convient et on obtient un bon résultat :

Notez que cette solution n'est pas absolument, exactement correct. Si vous avez besoin qu'il soit parfait, ou si vous voulez essayer de résoudre analytiquement des familles d'équations, vous devez vous tourner vers une bête plus compliquée : un solveur symbolique.

Un solveur symbolique, comme Mathematica ou Maple, est un système expert avec beaucoup de règles intégrées ("connaissances") sur l'algèbre, le calcul, etc. il "sait" que la dérivée de sin est cos, que la dérivée de kx^ p est kpx^(p-1), et ainsi de suite. Lorsque vous lui donnez une équation, il essaie de trouver un chemin, un ensemble d'applications de règles, d'où il se trouve (l'équation) jusqu'à l'endroit où vous voulez être (la forme la plus simple possible de l'équation, qui est, espérons-le, la solution) .

Votre exemple d'équation est assez simple, une solution symbolique pourrait ressembler à :

et il y a votre solution : x = 5.

J'espère que cela donne le goût de l'idée que les détails de la mise en œuvre (trouver un bon ensemble complet de règles et décider quand chaque règle doit être appliquée) peuvent facilement consommer de nombreuses années-homme d'efforts.


Oui, il a été ajouté dans la version 2.5. La syntaxe de l'expression est :

La première condition est évaluée, puis exactement l'un de a ou b est évalué et renvoyé en fonction de la valeur booléenne de condition . Si la condition est évaluée à True , alors a est évalué et renvoyé mais b est ignoré, ou bien lorsque b est évalué et renvoyé mais a est ignoré.

Cela permet un court-circuit car lorsque la condition est vraie, seul a est évalué et b n'est pas évalué du tout, mais lorsque la condition est fausse, seul b est évalué et a n'est pas évalué du tout.

Notez que les conditionnels sont un expression, pas un déclaration. Cela signifie que vous ne pouvez pas utiliser d'instructions d'affectation ou passer ou autre déclarations dans un conditionnel expression:

Vous pouvez cependant utiliser des expressions conditionnelles pour affecter une variable comme ceci :

Considérez l'expression conditionnelle comme une commutation entre deux valeurs. C'est très utile lorsque vous êtes dans une situation « une valeur ou une autre », mais ne fait pas grand-chose d'autre.

Si vous devez utiliser des instructions, vous devez utiliser un if normal déclaration au lieu d'un conditionnel expression.

Gardez à l'esprit qu'il est mal vu par certains Pythonistes pour plusieurs raisons :

  • L'ordre des arguments est différent de ceux de la condition classique ? a : b opérateur ternaire de nombreux autres langages (tels que C, C++, Go, Perl, Ruby, Java, Javascript, etc.), ce qui peut conduire à des bugs lorsque des personnes peu familiarisées avec le comportement "surpris" de Python l'utilisent (elles peuvent inverser l'argument ordre).
  • Certains le trouvent « incontrôlable », car il va à l'encontre du cours normal de la pensée (penser d'abord à la condition, puis aux effets).
  • Raisons stylistiques. (Bien que le 'inline if ' puisse être vraiment utile et rendre votre script plus concis, cela complique vraiment votre code)

Si vous avez du mal à vous souvenir de l'ordre, n'oubliez pas que lorsque vous lisez à haute voix, vous dites (presque) ce que vous voulez dire. Par exemple, x = 4 si b > 8 sinon 9 est lu à haute voix car x sera 4 si b est supérieur à 8 sinon 9 .


Questions fréquemment posées

Pourquoi pas une solution shell pure ?

Le shell standard POSIX/Single Unix Specification est un langage très limité qui ne contient pas de fonctionnalités pour représenter des séquences (liste ou tableaux) ou des tableaux associatifs (également appelés tables de hachage, cartes, dicts ou objets dans certains autres langages). Cela rend la représentation du résultat de l'analyse JSON quelque peu délicate dans les scripts shell portables. Il existe des moyens quelque peu rusés de le faire, mais beaucoup d'entre eux peuvent se briser si les clés ou les valeurs contiennent certains caractères spéciaux.

Bash 4 et versions ultérieures, zsh et ksh prennent en charge les tableaux et les tableaux associatifs, mais ces shells ne sont pas universellement disponibles (macOS a cessé de mettre à jour Bash à Bash 3, en raison d'un changement de GPLv2 à GPLv3, alors que de nombreux systèmes Linux n'ont pas zsh installé hors de la boîte). Il est possible que vous puissiez écrire un script qui fonctionnerait dans Bash 4 ou zsh, dont l'un est disponible sur la plupart des systèmes macOS, Linux et BSD de nos jours, mais il serait difficile d'écrire une ligne shebang qui fonctionne pour un tel écriture polyglotte.

Enfin, l'écriture d'un analyseur JSON à part entière dans le shell serait une dépendance suffisamment importante pour que vous puissiez tout aussi bien utiliser une dépendance existante comme jq ou Python à la place. Il ne s'agira pas d'une seule ligne, ou même d'un petit extrait de cinq lignes, pour faire une bonne implémentation.

Pourquoi ne pas utiliser awk, sed ou grep ?

Il est possible d'utiliser ces outils pour effectuer une extraction rapide à partir de JSON avec une forme connue et formatée d'une manière connue, comme une clé par ligne. Il y a plusieurs exemples de suggestions pour cela dans d'autres réponses.

Cependant, ces outils sont conçus pour des formats basés sur des lignes ou des enregistrements, ils ne sont pas conçus pour l'analyse récursive des délimiteurs correspondants avec des caractères d'échappement possibles.

Ainsi, ces solutions rapides et sales utilisant awk/sed/grep sont susceptibles d'être fragiles et de se briser si un aspect du format d'entrée change, comme la réduction des espaces blancs ou l'ajout de niveaux supplémentaires d'imbrication aux objets JSON, ou une citation échappée dans un string. Une solution suffisamment robuste pour gérer toutes les entrées JSON sans rupture sera également assez volumineuse et complexe, et donc pas trop différente de l'ajout d'une autre dépendance sur jq ou Python.

J'ai déjà dû faire face à de grandes quantités de données client supprimées en raison d'une mauvaise analyse des entrées dans un script shell, je ne recommande donc jamais de méthodes rapides et sales qui peuvent être fragiles de cette manière. Si vous effectuez un traitement ponctuel, consultez les autres réponses pour obtenir des suggestions, mais je recommande tout de même fortement d'utiliser un analyseur JSON testé existant.


Application du modèle révisé d'équation universelle de perte de sol (Rusle) pour évaluer l'érosion des sols dans le bassin de la rivière « Kalu Ganga » au Sri Lanka

L'érosion des sols est l'une des principales formes de dégradation des terres. L'érosion contribue à la perte de productivité des terres agricoles et des valeurs écologiques et esthétiques de l'environnement naturel, et elle nuit à la production d'eau potable et à la production d'hydroénergie. Ainsi, l'évaluation de l'érosion des sols et l'identification des terres les plus sujettes à l'érosion sont vitales pour le processus de gestion de l'érosion. Un modèle révisé d'équation universelle de perte de sol (Rusle) soutenu par un système SIG a été utilisé pour évaluer la variabilité spatiale de l'érosion se produisant à Kalu Ganga bassin fluvial au Sri Lanka. Le modèle numérique d'altitude (30 × 30 m), les données pluviométriques de vingt ans mesurées dans 11 stations pluviométriques à travers le bassin, les cartes d'utilisation des terres et des sols, et la littérature publiée ont été utilisés comme entrées pour le modèle. La perte annuelle moyenne de sol en Kalu Ganga bassin fluvial variait de 0 à 134 t ha −1 an −1 et la perte annuelle moyenne de sol a été estimée à 0,63 t ha −1 an −1 . Sur la base des estimations d'érosion, le paysage du bassin a été divisé en quatre classes de gravité d'érosion différentes : très faible, faible, modérée et élevée. Environ 1,68 % des zones (4714 ha) du bassin fluvial ont été identifiées avec une sévérité d'érosion modérée à élevée (>5 t ha −1 an −1 ) qui nécessite des mesures urgentes pour contrôler l'érosion des sols. Les terres avec des classes d'érosion des sols modérées à élevées ont été principalement trouvées dans Bulathsinghala, Kuruwita, et Rathnapura secrétariats divisionnaires. L'utilisation de l'information sur la gravité de l'érosion associée aux paramètres RUSLE individuels à l'échelle du bassin peut aider à concevoir les pratiques de gestion de l'utilisation des terres appropriées et une gestion améliorée basée sur les observations pour minimiser l'érosion du sol dans le bassin.

1. Introduction

L'érosion des sols est un processus naturel d'élimination des matériaux du sol et de transport par l'action d'agents érosifs tels que l'eau, le vent, la gravité et les perturbations humaines [1], et il a été accéléré par les activités humaines telles que l'agriculture intensive, la mauvaise gestion des terres , la déforestation et la culture sur des pentes abruptes [2]. Il s'agit d'un problème environnemental grave et continu lorsqu'il est associé à des précipitations de haute intensité induites par le climat [3]. La dégradation des terres agricoles par l'érosion des sols est un phénomène mondial entraînant une perte de sol de surface riche en nutriments, une augmentation du ruissellement d'un sous-sol plus imperméable et une diminution de la disponibilité de l'eau pour les plantes [4]. À l'échelle mondiale, le taux moyen d'érosion du sol dans les terres cultivées est d'environ 30 t ha −1 an −1 allant de 0,5 à 400 t ha −1 an −1 [5]. Les estimations indiquent qu'environ 85% de l'atténuation des terres, dans le monde, est due à l'érosion des sols réduisant la productivité des cultures d'environ 17%, affectant la fertilité des sols initialement et à long terme résultant de la désertion des terres [6].

Bien que l'érosion des sols soit un processus naturel, elle a été accélérée par les activités humaines telles que l'agriculture intensive, la mauvaise gestion des terres, la déforestation et la culture sur des pentes abruptes [2]. L'élimination de la couverture végétale et la mise en forme de la topographie de surface induisent ou accélèrent le déplacement et le mouvement du sol [7]. Une grave érosion des sols se produit dans la plupart des grandes régions agricoles du monde [5] en raison de l'expansion de l'agriculture sans pratiques adéquates de conservation des sols.

Plusieurs régions du Sri Lanka sont soumises à une grave érosion des sols [2, 8, 9]. La perte de sol dans les zones agricoles des hautes terres escarpées du centre du Sri Lanka est 10 à 100 fois plus élevée que les taux naturels d'érosion [8]. L'érosion des sols dans les terres maraîchères et à thé cultivées de manière intensive avec une mauvaise gestion des terres est plus élevée que dans les paysages forestiers ou dans les jardins de thé et les jardins familiaux bien gérés en Kurudu Oya sous-bassin versant du haut Mahaweli [9].

De plus, les résidus de récolte sont retirés pour le fourrage, les biocarburants et les utilisations industrielles, laissant les surfaces du sol dénudées d'une couverture protectrice augmentant la vulnérabilité des terres à l'érosion. Le ruissellement qui en résulte transporte finalement des sédiments, des matières organiques, des nutriments et des résidus de pesticides hors du site, ce qui a un impact sur la qualité de l'eau et du sol. Lorsque les terres sont laissées en jachère pour récupérer, le problème d'érosion est aggravé en raison d'une couverture végétale minimale [10]. On rapporte que l'érosion des sols augmente avec une plus grande ampleur des précipitations et des occurrences fréquentes de fortes précipitations [11].

L'érosion des sols et la dégradation des terres au Sri Lanka affectent la production alimentaire nationale et la durabilité des écosystèmes naturels [2]. Les taux d'érosion sont élevés dans les hautes terres ainsi que dans les basses terres en raison des changements d'utilisation des terres, y compris la suppression de la couverture végétale et l'urbanisation [7]. Plusieurs études menées au Sri Lanka pour évaluer l'érosion des sols, basées à la fois sur la modélisation numérique et la quantification réelle, ont montré que l'érosion des sols est un problème grave au Sri Lanka [12-15]. Par conséquent, il est utile d'identifier les zones les plus sujettes à l'érosion des sols, afin que les agriculteurs et les gestionnaires des terres puissent incorporer des mesures de conservation des sols appropriées pour minimiser l'érosion extensive des sols.

Il existe plusieurs approches de prédiction de l'érosion largement utilisées [16] comprenant des modèles empiriques, conceptuels et physiques [6, 17]. L'équation universelle de perte de sol (USLE), l'équation universelle modifiée de perte de sol (MUSLE) et l'équation universelle révisée de perte de sol (RUSLE) sont les modèles empiriques les plus populaires utilisés dans le monde pour la prédiction et le contrôle de l'érosion [14, 18]. RUSLE développé par le département américain de l'Agriculture est utilisé comme système d'aide à la décision dans la conservation des sols et la planification de l'utilisation des terres [19]. Il utilise un ensemble d'équations mathématiques pour décrire les processus écologiques liés aux pratiques de conservation et à l'érosion dans un paysage donné [20].

RUSLE est un outil flexible qui a été adapté aux échelles des paysages et des bassins versants combinés aux systèmes d'information géographique (SIG) [21-26] dans les évaluations de l'érosion des sols. L'étude de la perte annuelle de sol à l'aide du RUSLE basé sur le SIG dans le bassin versant de Pamba dans un paysage de montagne a démontré l'applicabilité du RUSLE dans l'étude des risques d'érosion où le taux d'érosion du sol est minimum dans les zones forestières naturelles et maximum dans les endroits soumis à l'influence humaine [22]. Au Sri Lanka, quelques études ont été menées pour évaluer l'érosion des sols à l'aide du modèle RUSLE [14, 15].

Kalu Ganga est le 4 ème fleuve le plus long (129 km) du Sri Lanka et entièrement situé dans la zone humide du pays [27]. En conséquence, il représente la plus grande quantité de rejets en mer du pays [28]. Il existe des aménagements d'eau potable et des mini et moyennes centrales hydroélectriques associées au fleuve [29]. De plus, la principale utilisation des terres du bassin est l'agriculture. Kalu Ganga bassin se trouve dans la zone où les précipitations induites par le climat devraient augmenter avec un potentiel élevé d'inondations et de glissements de terrain [30]. Ainsi, il vaut la peine d'analyser la variation spatiale de la perte de sol dans le bassin afin que le planificateur puisse prendre des précautions pour minimiser l'érosion du sol. La présente étude estime la perte annuelle moyenne de sol dans le Kalu Ganga bassin hydrographique en utilisant l'équation universelle révisée de perte de sol (RUSLE) en combinaison avec une interface ArcGIS pour développer la carte des risques d'érosion des sols du Rivière Kalu Ganga bassin.

2. Matériels et méthodes

2.1. Zone d'étude

Le Kalu Ganga Le bassin fluvial (2 766 km 2 ) est situé dans la partie sud-ouest du Sri Lanka. La longueur de la rivière est d'environ 130 km et s'étend de 80,00° à 80,67°E et de 6,42° à 6,83°N. Le Kalu Ganga commence dans les collines centrales du pays à une altitude de 2 250 m et se jette dans l'océan Indien près de la ville Kalutara après avoir traversé l'une des régions les plus pluvieuses du pays. La zone amont du bassin a un gradient plus élevé tandis que la zone aval du bassin est plus ou moins plate et l'altitude varie de 2149 m à 0 m [28] (Figure 1).


Manipulation de données de charge turbo avec des curseurs et des dictionnaires Python

par RichardFairhurs t

Les problèmes liés à l'utilisation des outils de calcul de champ, de jointure et de statistiques récapitulatives

Le calculateur de terrain est un excellent outil et facile à configurer, mais il présente plusieurs limitations qui peuvent sérieusement ralentir les routines scriptées lorsque vous devez effectuer de nombreuses manipulations de données avec de grands ensembles de données. La limitation la plus évidente est qu'un seul champ peut être calculé à la fois. Cela signifie souvent devoir traiter plusieurs fois chaque enregistrement de la classe d'entités afin de mettre à jour plusieurs champs. Si vous devez effectuer des transferts de données entre des classes d'entités à l'aide d'une jointure, il est essentiel d'indexer le champ de jointure dans les deux classes d'entités pour éviter les calculs qui prennent une éternité à traiter, et même dans ce cas, la vitesse est considérablement plus lente lorsqu'une jointure est impliquée. De plus, si vous devez réellement utiliser plusieurs champs pour créer une jointure qui corresponde correctement aux enregistrements entre les classes d'entités, votre seule option consiste à créer un nouveau champ dans les deux classes d'entités qui concatène ces valeurs de champ pour créer une jointure qui fonctionne. De plus, souvent avant que ces jointures puissent être créées, une table récapitulative doit être créée, ce qui prend plus de temps.

Heureusement, si vous disposez d'ArcGIS Desktop 10.1 ou d'une version ultérieure, il existe une alternative qui peut accélérer considérablement les scripts comme celui-ci et rendre les transferts de données entre les classes d'entités à la fois flexibles et incroyablement rapides. La solution est de remplacer le calculateur de champ par un ou plusieurs curseurs d'accès aux données (curseurs da) et de jointures et de créer des tableaux récapitulatifs avec un ou plusieurs dictionnaires python construits à l'aide d'un da SearchCursor.

Utilisation d'un curseur de mise à jour pour remplacer un calcul de champ dans une seule classe d'entités :

Vous trouverez ci-dessous un script simple qui utilisera un UpdateCursor sur une classe d'entités pour remplir un champ URL avec un lien hypertexte créé à l'aide d'une valeur extraite d'un autre champ. La méthode strftime est utilisée pour imprimer l'heure à laquelle le script démarre et l'heure à laquelle il se termine. Pour adapter ce script à vos propres données, il vous suffit de modifier le chemin et le nom de la classe d'entités à la ligne 7, les noms de champ dans la liste des champs à la ligne 9 et la chaîne d'URL à la ligne 14. Cela devrait fonctionner environ 7 fois plus rapidement qu'un calcul de champ similaire.

Utilisation d'un curseur de mise à jour pour remplacer plusieurs calculs de champ au sein d'une même classe d'entités :

Disons maintenant que nous devons en fait traiter 2 calculs de champ supplémentaires pour terminer la mise à jour de cette classe d'entités. Un calcul doit ajouter deux autres champs ensemble, et l'autre doit convertir les valeurs d'un champ des valeurs en majuscules en valeurs de casse de titre. Donc, s'il y a 100 000 enregistrements, tous ces enregistrements doivent être calculés 3 fois.

Tout cela peut être géré en un seul passage d'un UpdateCursor à travers les 100K enregistrements. Étant donné que les enregistrements ne doivent être modifiés qu'une seule fois et que l'ajout de plus de champs à lire ou à calculer par UpdateCursor prend très peu de temps supplémentaire à traiter, le gain de vitesse sur les calculs de 3 champs est beaucoup plus rapide que le script précédent. En conséquence, plus vous pouvez remplacer de calculs de champs avec un seul passage d'un UpdateCursor, plus la vitesse du script s'améliorera considérablement.

Vous trouverez ci-dessous le script qui peut effectuer les trois mises à jour de champ (supposez qu'il n'y a pas de valeurs Null dans les champs additionnés ou changeant de casse). Pour utiliser ce script avec vos propres données, il vous suffit de modifier les lignes 7, 9 et 14 (éventuellement modifier les calculs des lignes 16 et 18).

Utilisation d'un dictionnaire Python construit à l'aide d'un curseur de recherche pour remplacer une jointure reliant deux classes d'entités :

Une autre manipulation de données courante consiste à joindre une classe d'entités à une autre afin de transférer des valeurs de la classe d'entités jointe vers la classe d'entités cible à l'aide du calculateur de champs. Cependant, les entités chargées dans un dictionnaire Python à l'aide d'un curseur de recherche sont beaucoup plus rapides pour faire correspondre les valeurs de champ de jointure dans une classe d'entités à une autre qu'une jointure. Combiné à l'utilisation d'un UpdateCursor pour remplacer le calculateur de champ, la vitesse de ces types de manipulations de données peut être encore plus spectaculaire que les manipulations de données sur une seule classe d'entités.

Exemple 1 - Transfert d'une valeur de champ unique entre des classes d'entités

Vous trouverez ci-dessous le code requis pour transférer la valeur d'une classe d'entités à une autre en fonction d'une valeur de jointure commune dans un autre champ. Pour adapter ce script à vos propres données, modifiez les lignes 7 et 14 par le chemin et le nom de la source (Joindre) et mettez à jour (cible) la classe d'entités pour qu'elle corresponde aux classes d'entités que vous devez normalement rejoindre, modifiez les lignes 9 et 16 pour remplacer le champ list avec le nom du champ Join et le nom du champ en cours de transfert.

Exemple 2 - Transfert de plusieurs valeurs de champs entre des classes d'entités où il existe une correspondance 1:1 entre des ensembles de champs

Tout comme le calculateur de champs, plus le nombre de champs transférés d'une classe d'entités à l'autre est important, plus votre script s'accélérera. Si le transfert est un champ simple pour le transfert de champ, les champs de transfert peuvent être traités dans une boucle for. Vous trouverez ci-dessous un exemple de transfert de 5 champs correspondants entre deux classes d'entités. Pour adapter ce code à vos données, vous devez à nouveau modifier les classes d'entités aux lignes 7 et 14 et les listes de champs aux lignes 9 et 16.

Exemple 3 - Transfert de plusieurs valeurs de champs entre des classes d'entités impliquant des manipulations de champs complexes

Si vous devez effectuer des transferts de champs plus complexes qui font plus qu'un simple transfert de données d'une table à une autre, vous pouvez le faire en utilisant un code similaire aux exemples de calculs de champ qui ont été effectués sur une seule table. Voici les 3 mises à jour de champ de mon deuxième exemple de calcul de champ effectué entre deux tables distinctes avec des valeurs de jointure communes au lieu de toutes dans une seule table.

Création d'une clé de dictionnaire Python multi-champs pour remplacer un champ de jointure concaténé :

La gestion des valeurs de jointure multi-champs qui correspondent à des enregistrements entre deux classes d'entités est également possible à l'aide de dictionnaires et de curseurs sans avoir à concaténer des champs distincts dans un nouveau champ. La concaténation est toujours nécessaire, mais elle peut être manipulée à la volée en mémoire, ce qui est bien plus rapide que le calcul d'un champ. Vous trouverez ci-dessous un exemple de transfert de champ unique, mais cette fois en faisant correspondre les enregistrements à l'aide de 3 champs distincts pour définir les valeurs uniques entre les classes d'entités utilisées pour faire correspondre les enregistrements entre les classes d'entités.

Remplacement des jointures successives par le traitement simultané de plusieurs dictionnaires Python construits à l'aide da SearchCursors

Lorsque plusieurs jointures doivent être créées et supprimées pour effectuer des manipulations de données entre les tables, les gains de vitesse peuvent être encore augmentés, car vous pouvez créer plusieurs dictionnaires puis traiter toutes les relations de jointure simultanément lors d'un seul passage du curseur de mise à jour sur le classe d'entités mise à jour. Toutes les tables source doivent être lues dans les dictionnaires avant de traiter le curseur de mise à jour pour obtenir cet avantage. Plus vous pouvez remplacer de jointures de cette manière, plus la vitesse de votre script s'améliorera.

Vous trouverez ci-dessous un exemple où deux classes d'entités qui seraient normalement jointes à la classe d'entités mise à jour sont remplacées par des dictionnaires et traitées simultanément par une seule opération UpdateCursor.

Utilisation d'un dictionnaire Python construit à l'aide d'un curseur de recherche pour remplacer une table de sortie de statistiques récapitulatives

Un autre besoin courant consiste à créer un résumé d'une classe d'entités pour les valeurs uniques d'un ou de plusieurs champs couvrant plusieurs enregistrements. Le dictionnaire Python peut être utilisé à la place d'une sortie de tableau récapitulatif pour accomplir cela. L'avantage est que la sortie est stockée en mémoire et est beaucoup plus rapide à créer que la sortie d'un tableau récapitulatif réel. Vous trouverez ci-dessous un exemple de création d'un dictionnaire récapitulatif et de son utilisation pour mettre à jour la table source avec des valeurs de somme correspondant à ce champ et créer un champ de pourcentage dans la table source pour chaque enregistrement qui a généré le récapitulatif.

Une fois les modèles compris, il est possible de faire pratiquement tout ce que vous pouvez faire avec le calculateur de champs, une jointure ou un tableau récapitulatif à l'aide d'un curseur de mise à jour ou d'un dictionnaire python. En utilisant ces techniques de codage, j'ai pu réécrire plusieurs scripts qui effectuaient des manipulations de données en masse de sorte qu'au lieu de prendre plus d'une heure chacun à traiter, ils ne prennent désormais que 3 à 10 minutes à traiter. Plus vous pouvez remplacer ces opérations à l'aide d'un code comme celui-ci, plus vous réaliserez d'économies de temps de traitement. Les gains de performances peuvent être énormes, ce qui permet de maintenir les données à jour sans attendre trop longtemps ou sans consommer une grande partie de votre temps de traitement par lots après les heures normales. Il résout également les problèmes qui surviennent lorsque vous ne pouvez pas modifier le schéma de données source pour ajouter des index ou des concaténations de champs et qu'il n'est pas pratique de faire des copies des données.

si vous trouvez des erreurs dans l'exemple de code, faites-le moi savoir et je publierai une mise à jour sur ce blog pour signaler la correction. De plus, si vous avez besoin de plus de commentaires ajoutés au code pour vous aider à comprendre ce qui se passe, faites-le moi savoir et j'essaierai de commenter le code plus en détail. Ces exemples de code sont conçus pour fonctionner sur des fichiers de formes, des classes d'entités de géodatabase fichier et des classes d'entités SDE non versionnées. Des modifications de code supplémentaires sont nécessaires pour les faire fonctionner avec les classes d'entités SDE versionnées.

Je tiens à exprimer mes remerciements à Chris Synder qui m'a d'abord démontré l'utilité de ces techniques à travers le Forum et m'a aidé à comprendre comment les appliquer.


Ajout de géométrie

La géométrie est ajoutée à l'aide de l'une des trois méthodes suivantes : "null", "point" ou "poly". La méthode "null" est utilisée pour les formes nulles, "point" est utilisé pour les formes de points et "poly" est utilisé pour tout le reste.

Ajout d'une forme Null

Étant donné que les types de forme Null (type de forme 0) n'ont pas de géométrie, la méthode "null" est appelée sans aucun argument.

La liste des formes de l'objet écrivain aura désormais une forme nulle :

Ajout d'une forme de point

Les formes de points sont ajoutées à l'aide de la méthode "point". Un point est spécifié par une valeur x, y et facultative z (élévation) et m (mesure).

Ajout d'une forme poly

Les formes "poly" peuvent être des polygones ou des lignes. Les polygones de fichiers de formes doivent avoir au moins 5 points et le dernier point doit être le même que le premier (c'est-à-dire que vous ne pouvez pas avoir de triangle selon la spécification du fichier de formes même si de nombreux programmes SIG populaires prennent en charge de tels fichiers de formes.) Une ligne doit avoir au moins deux points. En raison des similitudes entre ces deux types de formes, ils sont créés à l'aide d'une méthode unique appelée "poly".


Voir la vidéo: Python Scripting: Buffer Analysis in Arcpy module. ArcGIS-Python. Everything for Beginners!