[PYTHON] Liste de contrôle pour éviter de transformer les éléments de array of numpy avec for

Si vous tournez l'élément de numpy.array avec une instruction for, la vitesse d'exécution diminuera considérablement.

Pour contourner le problème, essayez ceci un peu plus vite

--list Notation inclusive --Utilisez np.où si les conditions sont complexes --Utilisez np.frompyfunc (mais soyez prudent lorsque vous l'utilisez)

J'ai appris cela, donc ce mémorandum.

notation d'inclusion de liste

C'est déjà écrit partout,

import numpy as np
a = np.array(range(10))
a2 = []
for x in a:
    a2.append(x*2)

Si tu fais quelque chose comme ça

a2 = [x*2 for x in a]

L'histoire que vous devriez le faire. Ce sera beaucoup plus rapide à vivre.

Utilisez np.where si les conditions sont complexes

Par exemple, si vous voulez jouer avec le tableau a, mais que vous voulez déterminer les conditions en fonction des éléments du tableau b.

A titre d'exemple, considérons le cas où les éléments du tableau a sont doublés si les éléments du tableau b sont pairs, et les éléments du tableau a sont triplés sinon.

Utilisez np.where pour éviter de vouloir utiliser un index comme C ++ et tournez-le avec for.

import numpy as np
a = np.array(range(10))
print "a = ", a
b = a + 100
print "b = ", b

#Cela ressemble à ceci lors de l'utilisation de l'index
result1 = []
for i in range(10) :
    answer = a[i]*2 if b[i]%2 == 0 else a[i]*3
    result1.append(answer)
print np.array(result1)

# np.Si vous utilisez where et la fonction, vous pouvez écrire sur une ligne et c'est rapide

def func_double(x) :
    return x*2

def func_triple(x) :
    return x*3

result2 = np.where(b%2 == 0, func_double(a), func_triple(a))
print result2

Comme vous l'avez commenté, si c'est une fonction de ce degré, vous pouvez incorporer la fonction telle qu'elle est dans la notation d'inclusion de liste.

(Cependant, personnellement, je n'aime pas incorporer des fonctions directement dans la notation d'inclusion de liste ... Il est difficile de changer diverses choses plus tard, j'oublie de les changer, et un jeune étudiant avec une génération de python liste la première langue Si vous écrivez un code long et merdique dans la notation incluse, ce sera net comme "C'est vraiment difficile à lire !!!" (rires))

Utilisez np.frompyfunc (mais soyez prudent lorsque vous l'utilisez)

Quand je cherchais quelque chose d'un peu plus rapide, j'ai trouvé la page suivante, donc je vous remercie de l'utiliser.

Le moyen le plus rapide d'appliquer une fonction arbitraire à tous les éléments d'une liste Python Fonction de carte d'expérimentation d'accélération Python-

Alors, utilisons frompyfunc.

import numpy as np
# prepare input arrays
a = np.array(range(10))
print "array a is", a
b = a + 100
print "array b is", b

def addition(x, y):
    return x + y

np_addition = np.frompyfunc(addition, 2, 1)

print "print a + b using frompyfunc"
print np_addition(a, b)

print "print a + 1 using frompyfunc"
print np_addition(a, 1)

print "print 1 + b using frompyfunc"
print np_addition(1, b)

def subtruction(x, y):
    return x - y

np_subtruction = np.frompyfunc(subtruction, 2, 1)

print "using np.where and frompyfuncs"
result2 = np.where(b%2 == 0, np_addition(a, b), np_subtruction(a, b))
print result2

Les arguments de la fonction universelle créée par frompyfunc sont le premier objet fonction, le deuxième nombre d'arguments et le troisième nombre de valeurs de retour. Avec cela, si vous insérez un tableau dans l'argument d'une fonction universelle, le résultat de l'application de la fonction à chaque élément sera renvoyé sous forme de tableau.

Et s'il y avait une chose aussi pratique, j'aurais dû l'utiliser rapidement. Même en termes d'expérience, cela semble environ 30% plus rapide que la notation d'inclusion de liste.

Parce que la description était incorrecte, je vais la plier (je vais la plier pour ne plus refaire la même erreur à l'avenir)

Donc, ce que je voulais vérifier, c'est ** Est-il possible de passer un tableau à l'argument de la fonction universelle créée par ce frompyfunc et de faire du reste juste un float **? L'histoire.

Le résultat n'est pas du tout un problème! ~~ En d'autres termes, il renvoie le résultat calculé en ne modifiant que la partie où le tableau est passé pour chaque élément. ~~ ~~ De plus, quel que soit l'argument utilisé comme tableau, il sera décidé arbitrairement. ~~

~~ Génial! !! : souriant: ~~

(Correction) Ce n'était pas un tel problème, mais la fonction que les opérateurs + et de numpy utilisaient dans les fonctions d'addition et de soustruction acceptait simplement le tableau d'arguments et le scalaire (correction). Larmes) Donc, si vous mettez une simple liste au lieu de np.array dans les arguments a et b, l'exemple ci-dessus mourra.

C'est pourquoi j'ai supprimé la partie que j'avais écrite auparavant. (Fin de la correction) </ div>

Cependant, frompyfunc a certains aspects à prendre en compte, je vais donc le décrire ci-dessous.

Le dtype de la valeur de retour (tableau) de frompyfunc sera de type Object!

Dans la valeur de retour (numpy.array) de la fonction universelle créée par frompyfunc, dtype devient le type Object. (Le type de l'élément à l'intérieur est conservé)

C'est bien de simplement faire référence au contenu du tableau normalement, mais lorsque j'essaie de l'utiliser avec numpy.histogramadd, par exemple, je me fâche parce que je ne peux pas passer du type Object à d'autres types comme indiqué ci-dessous.

...numpy/lib/function_base.py", line 1014, in histogramdd
    flatcount = bincount(xy, weights)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

Pour éviter cela, vous pouvez convertir la valeur de retour numpy.array avec un type, mais ...

result2 = np.where(b%2 == 0, np_addition(a, b).astype(np.float64), np_subtruction(a, b).astype(np.float64))

Le problème est qu'un type est une fonction qui crée et renvoie un nouveau tableau, donc une copie du tableau se produit ici. Selon les conditions, ce temps de copie peut entraîner une vitesse d'exécution qui ne change pas même si elle est activée dans la notation d'inclusion de liste.

À propos de l'utilisation de la fonction universelle créée par np.where et frompyfunc ensemble

Dans les trois dernières lignes de l'exemple, il a été confirmé que la fonction universelle créée par np.where et frompyfunc peut être utilisée ensemble. Mais apparemment, cela est assez lent. C'était une erreur dans le programme que je pensais qu'il serait 10 fois plus lent à un moment donné, mais il semble que c'est environ deux fois plus lent. C'est pourquoi il semble difficile à utiliser dans des situations où la vitesse est importante.

Après tout, quel est le plus rapide?

Dans le cas d'un exemple simple comme celui donné ici, je pense que la notation d'inclusion de liste est presque la même.

Cependant, il y a des cas où vous ne voulez pas que la notation interne soit encombrée de fonctions et de conditions et que la lisibilité soit réduite, ou lorsque vous voulez faire un travail compliqué qui ne peut pas être écrit en une seule ligne en premier lieu. Dans un tel cas, je me suis rendu compte qu'il serait difficile de chercher et qu'il faudrait un temps inattendu pour écrire du code en utilisant le bon sens du langage que j'ai étudié il y a longtemps.

J'ai essayé divers plans pour accélérer le code que j'avais déjà écrit, mais à la fin, il est préférable de réécrire l'argument de la fonction qui est le matériau afin qu'il accepte à la fois le scalaire et le tableau depuis le début et se déplace rapidement. Je sens que c'est bien.

Si vous pouvez faire cela, la combinaison de np.where et des fonctions existantes aura l'air la plus propre et la plus rapide, et vous n'aurez pas à créer une fonction universelle avec frompyfunc.

Depuis que j'ai été une personne ayant appris les programmes en Fortran et C ++, j'ai écrit une fonction qui traite les données une par une, et écrit un programme qui n'est pas complètement hors de l'idée de le traiter en le tournant avec for. Si vous savez depuis le début que vous utiliserez numpy, numpy a de nombreuses fonctions qui gèrent rapidement les tableaux, j'ai donc pensé que c'était la bonne réponse de le concevoir pour traiter plusieurs enregistrements en tant que matrice depuis le début. pense.

Recommended Posts

Liste de contrôle pour éviter de transformer les éléments de array of numpy avec for
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
Un mémo sur la façon de surmonter le problème difficile de la capture d'effets avec l'IA
Comment extraire les conditions (acquérir tous les éléments du Groupe qui remplissent les conditions) pour Groupe par Groupe
Je veux déterminer l'authenticité d'un élément du tableau numpy
Comment connaître le nombre de GPU de python ~ Remarques sur l'utilisation du multitraitement avec pytorch ~
Comment modifier le niveau de journalisation d'Azure SDK pour Python
Comment obtenir l'ID de Type2Tag NXP NTAG213 avec nfcpy
Comment surveiller l'état d'exécution de sqlldr avec la commande pv
Comment utiliser Jupyter sur le frontal de Spacon ITO
Comment utiliser l'apprentissage automatique pour le travail? 01_ Comprendre l'objectif de l'apprentissage automatique
Comment mettre à jour la version Python de Cloud Shell dans GCP
Pour ceux d'entre vous qui ne savent pas comment définir un mot de passe avec Jupyter sur Docker
Comment exécuter le code pratique du livre "Making Profitable AI with Python" sur Google Colaboratory
Comment couper la partie inférieure droite de l'image avec Python OpenCV
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
[Reconnaissance d'image] Comment lire le résultat de l'annotation automatique avec VoTT
La deuxième nuit de la boucle avec pour
L'histoire de la tentative de pousser SSH_AUTH_SOCK obsolète avec LD_PRELOAD à l'écran
python: Astuces pour afficher un tableau (liste) avec un index (comment savoir quel numéro est un élément d'un tableau)
Utile pour changer les permissions sur Linux! Comment compter jusqu'à 31 d'une seule main.
Comment publier un blog sur Amazon S3 avec le moteur de blog statique `` Pélican '' pour Pythonista
Comment la référence du tableau python change en fonction de la présence ou de l'absence d'indices
Comment obtenir la clé sur Amazon S3 avec Boto 3, exemple de mise en œuvre, notes
[python] Comment trier par le Nth Mth élément d'un tableau multidimensionnel
[Python] Comment enregistrer des images sur le Web à la fois avec Beautiful Soup
Remarque: Comment obtenir le dernier jour du mois avec python (ajouté le premier jour du mois)
Comment obtenir une liste de fichiers dans le même répertoire avec python
Comment calculer la volatilité d'une marque
Comment utiliser MkDocs pour la première fois
Stratégie sur la façon de monétiser avec Python Java
Trier les éléments d'un tableau en spécifiant des conditions
Comment essayer l'algorithme des amis d'amis avec pyfof
Comment spécifier des attributs avec Mock of Python
Comment implémenter "named_scope" de RubyOnRails avec Django
Comment installer OpenGM sur OSX avec macports
Introduction à Python avec Atom (en route)
Comment éviter BrokenPipeError avec la note DataLoader de PyTorch
Comment obtenir des éléments de type dictionnaire de Python 2.7
Comment entraîner Kaldi avec JUST Corpus
Comment trouver la corrélation pour les variables catégorielles
Comment créer des nombres aléatoires avec le module aléatoire de NumPy
Comment lire des données originales ou des données externes sur Internet avec scikit-learn au lieu d'un ensemble de données attaché tel que l'iris
Comment définir un dossier partagé avec le système d'exploitation hôte dans CentOS7 sur Virtual BOX
La première étape de l'apprentissage automatique ~ Pour ceux qui veulent essayer l'implémentation avec python ~
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
Comment éviter l'étiquette de coupure du graphique créé par le module système de tracé à l'aide de matplotlib
Je veux tracer les informations de localisation de GTFS Realtime sur Jupyter! (Avec ballon)
Un moyen simple de remplir le début de 0 en fonction du nombre de chiffres dans le nombre [Python]
Comment compter le nombre d'occurrences de chaque élément de la liste en Python avec poids
Comment définir l'environnement de développement pour chaque projet avec VSCode + extension Python + Miniconda
Le 15e temps réel hors ligne, j'ai essayé de résoudre le problème de l'écriture avec python
Comment connaître le numéro de port du service xinetd
Réfléchissez à la programmation de Python sur votre iPad
Ajouter des attributs d'objets de classe avec une instruction for