Suite

Répliquer l'outil de statistiques récapitulatives avec un champ de cas en utilisant son propre calcul dans ModelBuilder ?

Répliquer l'outil de statistiques récapitulatives avec un champ de cas en utilisant son propre calcul dans ModelBuilder ?


Je pensais que ce serait un problème simple à résoudre, car ma recherche sur Google n'a pas fourni de réponses jusqu'à présent.

J'ai créé une table proche (à l'aide de la "Générer une table proche" dans Arc) comparant deux ensembles de points, et j'ai inclus l'option d'obtenir les 10 points les plus proches pour chacun des points d'entrée. Donc, pour chacun des points d'entrée, j'ai 10 caractéristiques proches (cela peut être vu dans la colonne IN_FID).


Je souhaite calculer la distance moyenne, plus l'angle moyen (que j'ai converti en un relèvement 0-360) des 10 points pour chaque valeur unique dans IN_FID. J'utilise l'outil de statistiques récapitulatives avec le champ de cas défini sur IN_FID pour obtenir la distance moyenne, mais pour obtenir le relèvement moyen, je dois exécuter un calcul qui prend en compte les statistiques circulaires.

Ma solution jusqu'à présent dans ModelBuilder consiste à utiliser l'itérateur 'Sélection de ligne' avec le IN_FID défini comme 'option Grouper par champ', j'exécute ensuite le champ de calcul sur la sortie pour mon relèvement moyen. Ainsi, pour chaque valeur unique de la colonne IN_FID, j'ai un relèvement moyen (à partir de 10 points). Cependant, ce processus est très lent, il prend environ 3 secondes pour chaque IN_FID unique, et avec 10 000 points, il dure 8 heures de traitement.

L'outil de statistiques récapitulatives fonctionne en quelques secondes, donc je me demandais s'il y avait un script python que je pouvais écrire et exécuter dans le bloc de code de l'outil de calcul de champ, cela signifie que je n'ai pas à utiliser l'itérateur "Sélection de ligne" et accélérer ce processus ? (cependant, je ne suis même pas sûr que cela l'accélérera!). Mon python n'est pas à la hauteur pour le moment, mais mes recherches m'ont amené à penser que je dois utiliser le curseur de recherche ou de mise à jour, et certains (imbriqués?) Pour les boucles, mais je n'ai pas les connaissances pour appliquer et écrire ceci encore, mais j'apprends en utilisant divers exemples que je trouve en ligne.

Quelqu'un a-t-il des exemples de script python qui effectuent une tâche similaire que je pourrais utiliser comme base pour cette tâche ou qui peut m'orienter vers des tutoriels utiles ?

Ou avez-vous des méthodes alternatives pour surmonter ce problème auxquelles je n'ai pas pensé ?


N'utilisez jamais de boucles de curseur imbriquées. Plus jamais! Le concept de boucles de curseur imbriquées est totalement inutile.

Utilisez un dictionnaire pour collecter des informations à partir d'un curseur de recherche pour chaque IN_FID en tant que clé. La recherche de l'IN_FID à partir du dictionnaire est pratiquement instantanée et devrait traiter 10 000 points en 1 minute ou moins.

Les dictionnaires peuvent être remplis à partir d'un curseur de recherche pour effectuer des opérations statistiques au fur et à mesure de la lecture de chaque enregistrement, ou vous pouvez d'abord collecter toutes les valeurs associées à chaque clé FID dans une liste dans le dictionnaire, puis utiliser une boucle for pour effectuer des opérations statistiques ordonnées. après avoir trié la liste. Ces processus en mémoire sont extrêmement rapides. La valeur récapitulative ou les ensembles de valeurs peuvent être réenregistrés dans le dictionnaire. Enfin, vous écrivez toutes vos valeurs statistiques finales à l'aide d'un curseur de mise à jour qui recherche chaque IN_FID dans le dictionnaire pour obtenir la valeur récapitulative que vous devez écrire, ou vous pouvez créer une nouvelle table et la remplir à l'aide d'un curseur d'insertion.

Voir mon blog sur la manipulation de données de charge turbo à l'aide de curseurs et de dictionnaires Python. En particulier, consultez la section sur l'utilisation d'un dictionnaire Python construit à l'aide d'un curseur de recherche pour remplacer un tableau de sortie de statistiques récapitulatives.

J'aurais besoin de savoir quel processus statistique circulaire vous effectuez avec vos distances et vos angles pour proposer une modification du script qui conviendrait exactement à vos besoins. Mais je suis sûr que le contour de base du script est ce dont vous avez besoin et peut être modifié pour faire ce que vous voulez, et que cela répondra à vos attentes de performance.


En utilisant le post de Richard Fairhurt et ce post pour la moyenne des roulements, j'ai trouvé la solution suivante :

import math import arcpy fc= "e:/NCCA/Temp/Temp.gdb/near_table" bears = ["IN_FID", "bearing", "bearing_avg"] #crée un dictionnaire avec IN_FID comme clé, et le relèvement comme les valeurs valueDict = {} avec arcpy.da.SearchCursor(fc, roulements) comme searchRows : pour searchRow dans searchRows : keyValue = searchRow[0] sinon keyValue dans valueDict : valueDict[keyValue] = [searchRow[1]] sinon : valueDict[keyValue].append(searchRow[1]) #calcule la moyenne de relèvement des valeurs pour chaque clé de dictionnaire et place la relèvement moyen dans un nouveau dictionnaire averageBearingDict = {} pour la clé dans valueDict : cosSum = 0,0 sinSum = 0,0 pour BearingVal dans valueDict[clé]: theCos = math.cos(math.radians(float(bearingVal))) theSin = math.sin(math.radians(float(bearingVal))) cosSum += theCos sinSum += theSin N = len( valueDict[key]) C = cosSum/NS = sinSum/N theMean = math.atan2(S,C) si theMean < 0.0: theMean += math.radians(360.0) theMean_deg = math.degrees(theMean) averageBearingDict[key] = theMean_deg #ce pu ts la moyenne de relèvement calculée dans le tableau - dans la ligne "bearing_avg" avec arcpy.da.UpdateCursor(fc, roulements) comme rangées : pour la rangée dans les rangées : rangée[2] = averageBearingDict[row[0]] rows.updateRow( ligne)

Cela a été exécuté comme un script autonome et se termine en moins d'une minute.


Voir la vidéo: Using Parameters in ModelBuilder