Suite

Utiliser des ensembles de sélection avec Python


J'essaie de créer un modèle qui lit environ 30 classes d'entités ponctuelles différentes et ajoute uniquement les entités sélectionnées à une nouvelle classe d'entités. Certaines classes d'entités n'ont aucun enregistrement sélectionné, il ajoute donc chaque enregistrement de cette classe d'entités. Existe-t-il un moyen d'exclure ces fonctionnalités de l'ajout ? Dans le passé, nous utilisions une macro VBA pour lire chaque classe d'entités et utilisons des ensembles de sélection pour déterminer si l'un des enregistrements est sélectionné, mais je ne sais pas comment obtenir cette même fonctionnalité à l'aide de Python.


Si vous utilisez python (comme votre balise le suggère) et ArcGIS (peut-être ?), vous pouvez faire quelque chose comme ça… (édité)

# Vérifiez qu'il y a au moins une fonctionnalité sélectionnée. ftrCountBefore = int(arcpy.GetCount_management(layer).getOutput(0)) # ToDo Effectuer une sélection # ftrCountAfter = int(arcpy.GetCount_management(layer).getOutput(0)) if (not (ftrCountBefore == ftrCountAfter)): doSomething

Instruction de sélection Python SQL

Dans cette section, nous vous expliquons comment écrire une instruction SQL Select dans le langage de programmation Python. Et comment extraire ou sélectionner les enregistrements d'une table SQL Server.

Avant d'entrer dans l'exemple d'instruction Python SQL Select, laissez-moi vous montrer les données que nous allons utiliser.


2 réponses 2

Je suis d'accord avec @Reinderien que cela ne devrait pas être un cours. Vous pouvez en voir la preuve dans votre constructeur :

Vous construisez l'objet (et appelez le constructeur) simplement pour appeler self.__iter__() . Il n'y a aucune raison pour la création d'un objet ici juste pour trier la liste. Si vous aviez besoin de maintenir un état entre les sortes ou quelque chose (je ne sais pas pourquoi vous le feriez cependant), alors il mai Être approprié.

Je ferai également remarquer que vous essayez de violer au moins deux "contrats" avec votre utilisation de __init__ et __iter__ :

aucune valeur non-None ne peut être renvoyée par __init__(), cela entraînera la levée d'une TypeError au moment de l'exécution.

Maintenant, tu n'es pas en fait renvoyer quoi que ce soit, mais votre indice de type dit que vous l'êtes. Si vous envisagez d'utiliser l'indication de type, les indications doivent indiquer plus clairement quels types sont impliqués, et non faire de fausses déclarations.

Cette méthode doit renvoyer un nouvel objet itérateur qui peut itérer sur tous les objets du conteneur

Le problème est que vous retournez une liste, et une liste n'est pas un itérateur, c'est un itérable (il possède un itérateur). Ce n'est pas seulement un problème théorique. Notez comment cela peut vous mordre:

L'utilisation de méthodes "dunder" peut être utile pour écrire du code propre, mais seulement si vous n'en abusez pas. Assurez-vous de lire la documentation et de comprendre le but et les contrats des méthodes avant d'essayer de les utiliser.

Et en ce qui concerne les conseils de type, vous pouvez utiliser un TypeVar pour permettre au vérificateur de type de voir la cohérence entre les types d'éléments entrant et sortant de votre fonction de tri. Après avoir transformé votre classe en une fonction autonome, vous avez essentiellement :

Le problème avec ceci est qu'il ne dit pas au vérificateur quelle est la relation entre les types d'éléments dans input_list et celui de la liste que selection_sort renvoie. Cela peut conduire à des problèmes subtils où il ne sera pas en mesure de vous aider avec les types :

Vous pouvez résoudre ce problème en introduisant un TypeVar qui lui indique que le type d'élément reste cohérent. Je passe également de l'utilisation de la liste à la liste, car la liste ne semble pas encore prendre en charge les génériques :

Maintenant, il est capable de déduire le type de x , et peut vous donner de meilleurs achèvements et avertissements de type.


Exécution de &ldquoSELECT &hellip WHERE &hellip IN &hellip&rdquo à l'aide de MySQLdb

J'ai un problème pour exécuter du SQL à partir de Python, bien que SQL similaire fonctionne correctement à partir de la ligne de commande mysql.

Le tableau ressemble à ceci :

Je peux exécuter la requête SQL suivante à partir de la ligne de commande mysql, sans problème :

Cependant, lorsque j'essaie de faire la même chose depuis Python, je n'obtiens aucune ligne, alors que je m'attendais à 2 lignes :

La question est donc : comment le code python doit-il être modifié pour sélectionner ces fooid s où se trouve la barre ('A','C') ?

Soit dit en passant, j'ai remarqué que si je change les rôles de bar et de fooid , je peux obtenir le code pour sélectionner avec succès les barres où se trouve fooid (1,3). Je ne comprends pas pourquoi une telle requête (ci-dessous) fonctionne, tandis que l'autre (ci-dessus) ne fonctionne pas.

Et juste pour être absolument clair, voici comment la table foo a été créée :

Éditer: Lorsque j'active le journal général des requêtes avec mysqld -l /tmp/myquery.log, je vois

En effet, il semble que trop de guillemets soient placés autour de A et C .

Grâce au commentaire de @Amber, je comprends mieux ce qui ne va pas. MySQLdb convertit l'argument paramétré ['A','C'] en ("'A'","'C'") .

Existe-t-il un moyen de créer une requête paramétrée à l'aide de la syntaxe IN SQL ? Ou faut-il construire manuellement la chaîne SQL ?


Solution¶

Pour trouver le nombre de déplacements effectués par chaque ménage, nous pouvons créer une colonne fictive avec la valeur 1 et utiliser la méthode .groupby() pour compter le nombre total de déplacements pour chaque ménage. Ensuite, nous fusionnons ces informations avec les informations sur les ménages pour obtenir la base de données finale.

hh_id trip_count Sans nom : 0 home_mgra le revenu voitures transpondeur cdap_pattern jtf_choice autotech tncmemb
0 1690841 20 426629 7736 512000 2 1 MMMM0 0 0 0
1 1690851 12 426645 7736 68200 4 1 HNM0 0 0 0
2 1690853 8 426643 7736 127000 2 0 MMMH0 0 0 0
3 1690856 23 426642 7736 59500 4 1 MMMMMM0 0 0 0
4 1690858 5 426640 7736 200030 1 0 M0 0 0 0

Ensuite, nous créons un tableau croisé dynamique en utilisant les colonnes autos et trip_count dans le dataframe comme index et les colonnes dans la méthode .pivot_table(). Nous utilisons aggfunc = 'taille' pour obtenir le nombre de ménages dans ce tableau à deux dimensions.

Enfin, nous créons une carte thermique à l'aide du package seaborn. Nous pouvons ajuster la hauteur et la largeur de la carte thermique en utilisant plt.figure(figsize = (width, height)) . Assurez-vous de spécifier la taille de la figure avant de créer une carte thermique.

Nous pouvons définir annot = True dans sns.heatmap() pour obtenir les nombres visibles dans le tracé. En outre, il existe d'autres arguments que nous pouvons spécifier pour obtenir la carte thermique au format souhaité.

À partir de la carte thermique que nous venons de créer, nous pouvons facilement trouver des réponses en regardant les chiffres ainsi que la carte des couleurs.

Pour les ménages avec 2 automobiles, 6 est le nombre de déplacements par jour le plus courant, bien que 4 déplacements soit un bon deuxième.

Pour les ménages ne faisant que 2 déplacements par jour, la grande majorité d'entre eux possèdent 1 automobile.


Limiter les coûts de requête en limitant le nombre d'octets facturés

Meilleur entrainement: Utilisez le paramètre Nombre maximal d'octets facturés pour limiter les coûts de requête.

Vous pouvez limiter le nombre d'octets facturés pour une requête à l'aide du paramètre Nombre maximal d'octets facturés. Lorsque vous définissez le nombre maximal d'octets facturés, le nombre d'octets que la requête lira est estimé avant l'exécution de la requête. Si le nombre d'octets estimés dépasse la limite, la requête échoue sans frais.

Pour les tables en cluster, l'estimation du nombre d'octets facturés pour une requête est une limite supérieure et peut être supérieure au nombre réel d'octets facturés après l'exécution de la requête. Ainsi, dans certains cas, si vous définissez le nombre maximal d'octets facturés, une requête sur une table en cluster peut échouer, même si le nombre réel d'octets facturés ne dépasse pas le paramètre maximal d'octets facturés.

Si une requête échoue en raison du paramètre de nombre maximal d'octets facturés, une erreur semblable à la suivante est renvoyée :

Erreur : La requête a dépassé la limite d'octets facturés : 1000000. 10485760 ou supérieur requis.

Pour définir le nombre maximum d'octets facturés :

Console

  1. Dans le Éditeur de requêtes, Cliquez sur Suite, Cliquez sur Paramètres de requête, puis cliquez sur Options avancées.
  2. Dans le Nombre maximal d'octets facturés champ, entrez un nombre entier.
  3. Cliquez sur Sauvegarder.

Utilisez la commande de requête bq avec l'indicateur --maximum_bytes_billed.

Définissez la propriété maximumBytesBilled dans JobConfigurationQuery ou QueryRequest .


Presque fini! Lancez à nouveau cet éditeur de texte et laissez le script sortir du Python. Tout d'abord, nous devons importer le module ctypes. Ensuite, si vous êtes comme moi, vous voudrez mettre le chemin absolu du fichier .so dans sa propre variable. Ainsi, le haut de mon pyfactorial.py ressemble à ceci :

La prochaine chose que nous voulons faire est de créer notre objet cdll à partir de notre fichier .so précédemment créé. Donc, après l'affectation de la variable so_file, mettez :

Maintenant, techniquement, à ce stade, vous pouvez commencer à jouer avec l'appel de la fonction C dans le script Python en exécutant python dans la ligne de commande, mais soyons d'abord un peu responsable. Avant de jouer un peu plus avec, encapsulons notre fonction C dans une fonction Python. Après avoir créé la variable factorielle, créez la fonction suivante :

Enregistrez ce fichier sous le nom pyfactorial.py. Au total, cela devrait ressembler à ceci:

Notez que la façon d'appeler des fonctions dans le fichier d'objet partagé C importé consiste à dire <CDLL Object>.<function name à partir du code C>(<parameter>) . Facile!

Donc, fondamentalement, chaque fois que nous voulons utiliser cette fonction C dans Python, nous appelons la fonction factorielle qui exécutera la fonction C avec le paramètre transmis par l'utilisateur et évaluera le résultat. Si la fonction C renvoie -1 (rappelez-vous que nous l'avons mis là), le script Python sait qu'il y a eu un problème. Sinon, il renverra le numéro. Essayons-le ! Lancez votre terminal et démarrez python

Ta-da !! C'est l'idée de base derrière l'utilisation des fonctions C en Python. C'est certainement un outil qui vaut la peine d'avoir. Appliquez toutes vos autres connaissances en programmation pour créer des fonctions et des fonctionnalités impressionnantes, et faites-moi savoir si vous avez des questions.


/dev/polll Objets d'interrogation¶

Solaris et ses dérivés ont /dev/poll . Alors que select() est O (descripteur de fichier le plus élevé) et poll() est O (nombre de descripteurs de fichiers), /dev/poll est O (descripteurs de fichiers actifs).

Le comportement de /dev/poll est très proche de l'objet poll() standard.

Fermez le descripteur de fichier de l'objet d'interrogation.

True si l'objet d'interrogation est fermé.

Renvoie le numéro de descripteur de fichier de l'objet d'interrogation.

Enregistrez un descripteur de fichier avec l'objet d'interrogation. Les futurs appels à la méthode poll() vérifieront alors si le descripteur de fichier a des événements d'E/S en attente. fd peut être soit un entier, soit un objet avec une méthode fileno() qui renvoie un entier. Les objets fichier implémentent fileno() , ils peuvent donc également être utilisés comme argument.

masque d'événement est un masque de bits facultatif décrivant le type d'événements que vous souhaitez rechercher. Les constantes sont les mêmes qu'avec l'objet poll(). La valeur par défaut est une combinaison des constantes POLLIN , POLLPRI et POLLOUT .

L'enregistrement d'un descripteur de fichier déjà enregistré n'est pas une erreur, mais le résultat n'est pas défini. L'action appropriée consiste à le désenregistrer ou à le modifier d'abord. C'est une différence importante par rapport à poll() .

Cette méthode fait un unregister() suivi d'un register() . C'est (un peu) plus efficace que de faire la même chose explicitement.

Supprimer un descripteur de fichier suivi par un objet d'interrogation. Tout comme la méthode register(), fd peut être un entier ou un objet avec une méthode fileno() qui renvoie un entier.

Tenter de supprimer un descripteur de fichier qui n'a jamais été enregistré est ignoré en toute sécurité.

Sonde l'ensemble des descripteurs de fichiers enregistrés et renvoie une liste éventuellement vide contenant (fd, event) 2-uplets pour les descripteurs qui ont des événements ou des erreurs à signaler. fd est le descripteur de fichier, et un événement est un masque de bits avec des bits définis pour les événements signalés pour ce descripteur — POLLIN pour l'attente d'entrée, POLLOUT pour indiquer que le descripteur peut être écrit, et ainsi de suite. Une liste vide indique que l'appel a expiré et qu'aucun descripteur de fichier n'a eu d'événement à signaler. Si temps libre est donné, il spécifie la durée en millisecondes pendant laquelle le système attendra les événements avant de revenir. Si temps libre est omis, -1 ou None , l'appel sera bloqué jusqu'à ce qu'il y ait un événement pour cet objet d'interrogation.

Modifié dans la version 3.5 : La fonction est maintenant réessayée avec un délai d'attente recalculé lorsqu'elle est interrompue par un signal, sauf si le gestionnaire de signal lève une exception (voir PPE 475 pour la justification), au lieu de lever InterruptedError .


1 réponse 1

Comme mentionné dans la revue précédente, l'expression lambda dans lambda s: shell_sort(s, 5) n'est plus nécessaire une fois que le deuxième paramètre de shell_sort a une valeur par défaut, car la fonction peut être appelée par shell_sort(input_list) comme les autres fonctions . Par conséquent, l'utilisation de shell_sort est suffisante.

Ce morceau de code n'est pas correctement écrit.

Comme suggéré par d'autres dans l'examen précédent, les fonctions modifient l'entrée en place. Il est donc préférable de ne pas renvoyer de liste (simplement omettre les instructions return). Et cela s'appelle ainsi :

Dans les petits programmes, les cas de test peuvent être mieux organisés sous forme de liste ou de tuple et itérés pendant les tests, de la même manière que les fonctions testées. Cela facilite l'ajout de nouveaux cas de test (créés manuellement ou générés automatiquement). Pour des projets plus importants, il faudrait d'autres outils tels que pytest .

Notez également que les cas de test doivent être conçus pour couvrir différents types d'entrées qui passent par différentes branches de code, y compris les cas extrêmes qui peuvent éventuellement conduire à des bogues. Ici, les tests sur les flottants réussissent tant que les tests sur les entiers correspondants réussissent. Il n'est donc pas nécessaire de répéter chaque test pour les entiers et les flottants. En d'autres termes, tant que les opérateurs de comparaison sont bien définis, le type d'entrées n'est pas une caractéristique pouvant conduire à un comportement différent des fonctions testées. Vous devez plutôt rechercher d'autres variantes, comme indiqué dans l'exemple de code ci-dessus.

En remarque, l'exemple de code montre également la génération de nombres aléatoires à l'aide du module aléatoire afin que scipy ne soit plus nécessaire.


1 réponse 1

Voici un exemple trivial, qui capture l'essence des algorithmes génétiques de manière plus significative que le polynôme que vous avez fourni. Le polynôme que vous avez fourni peut être résolu via la descente de gradient stochastique , qui est une technique de minimisation plus simple. Pour cette raison, je suggère plutôt cet excellent article et exemple de Will Larson.

Définir un problème à optimiser Nous allons maintenant mettre en place un exemple simple d'utilisation d'un algorithme génétique en Python. Nous allons optimiser un problème très simple : essayer de créer une liste de N nombres égaux à X lorsqu'ils sont additionnés.

Si nous fixons N = 5 et X = 200, alors ce seraient toutes des solutions appropriées.

Jetez un œil à l'article en entier, mais voici le code complet:

Je pense qu'il pourrait être très utile sur le plan pédagogique de résoudre également votre problème d'origine à l'aide de cet algorithme, puis de construire une solution à l'aide de la recherche par grille stochastique ou de la descente de gradient stochastique et vous obtiendrez une compréhension approfondie de la juxtaposition de ces trois algorithmes.