J'étais désemparé lors de l'écriture du programme moi-même, donc je vais l'écrire sous forme de mémo. Si vous connaissez une meilleure solution, veuillez la signaler.
※environnement
J'obtiens un ZeroDivisionError
lorsque je fais une division 0 normale en Python.
python
try:
divided = 1 / 0
except ZeroDivisionError as e:
print(f'ZeroDivisionError: {e}')
# -> ZeroDivisionError: division by zero
D'un autre côté, si vous divisez par 0 avec numpy, RuntimeWarning
se produira, mais le résultat sera affiché sans arrêter le traitement.
python
import numpy as np
divided = 1 / np.array(0)
print(devided)
# -> inf
# -> RuntimeWarning: divide by zero encountered in true_divide
Le résultat du calcul de "1 / np.array (0)" est l'objet "numpy.inf" qui représente l'infini avec numpy. Cela donne un avertissement, mais cela n'arrête pas le processus, donc cela semble à mi-chemin. Il appartient peut-être à l'utilisateur de dire: "Je peux le calculer, mais je vais vous donner un avertissement. Je vous laisse le soin". Alors, réfléchissons à ce qu'il faut faire lorsque vous souhaitez arrêter le processus et lorsque vous autorisez le processus et ignorez l'avertissement.
Vous pouvez utiliser warnings.simplefilter
pour faire de RuntimeWarning
une exception ou l'ignorer.
python
import warnings
import numpy as np
warnings.simplefilter('error', category=RuntimeWarning) #Définir l'avertissement d'exécution comme exception
a = np.array(0) #Variables qui ne devraient pas contenir 0
divided = 1 / a
print(divided)
# -> RuntimeWarning: divide by zero encountered in true_divide
# divided = 1 /Le traitement s'arrête à a et imprimer(divided)N'est pas exécuté
python
import warnings
import numpy as np
warnings.simplefilter('ignore', category=RuntimeWarning) #Définir l'avertissement d'exécution pour ignorer
a = np.array(0) #Variables pouvant contenir 0
divided = 1 / a
print(divided)
# -> inf
#Aucun avertissement n'est émis et le traitement se poursuit
Cependant, à ce moment, le contrôle est appliqué à RuntimeWarning
autre que la division 0, il y a donc un risque que le bogue ne puisse pas être capturé, surtout s'il est ignoré. Alors je pense à une autre méthode
(En réponse au commentaire, j'ai ajouté numpy.seteer
.)
Vous pouvez utiliser numpy.seteer
pour définir un contrôle plus fin de Avertissement
.
python
import numpy as np
np.seterr(divide='ignore') #Ignorer uniquement l'avertissement d'exécution de la division 0
a = np.array(0)
divided = 1 / a
print(divided)
# -> inf
Vous pouvez maintenant ajouter un contrôle uniquement à la division 0. La complexité de "l'importation" des avertissements "a également été éliminée.
Cependant, dans ce cas, ce contrôle s'applique à tout le code source. Si possible, je veux minimiser l'étendue du contrôle.
Vous pouvez changer de contrôle en écrivant numpy.seterr
avant et après la division, mais envisagez une description plus intelligente.
(C'est également la partie ajoutée des commentaires signalés)
En utilisant numpy.errstate
, le contrôle par le gestionnaire de contexte est possible.
python
import numpy as np
a = np.array(0)
with np.errstate(divide='ignore'): #Appliquer le contrôle uniquement dans la portée
divided = 1 / a
print(divided)
# -> inf
divided = 1 / a #L'avertissement d'exécution se produit car il est hors de portée de la négligence
# -> RuntimeWarning: divide by zero encountered in true_divide
Cela réduira la portée des changements de contrôle et complètera les bogues causés par des divisions (non autorisées) ailleurs.
Dans l'exemple, nous avons considéré la division des nombres dans un souci de clarté, mais vous pouvez également contrôler la division du tableau.
python
import numpy as np
a = np.array([1, 2, 0])
with np.errstate(divide='ignore'): #Appliquer le contrôle uniquement dans la portée
divided = 1 / a
print(divided)
# -> [1. 0.5 inf]
Si vous voulez diviser un nombre, vous pouvez simplement écrire une instruction if, mais c'est difficile pour un tableau, donc je pense que cette méthode de contrôle sera utile.
Au début, je ne connaissais pas «numpy.errstate» et j'ai pensé à l'écrire comme suit.
python
import numpy as np
a = np.array([1, 2, 0])
divided = np.full(len(a), np.inf) #Tous les éléments sont np.Faire un tableau d'inf
nonzero_indices = np.where(a != 0)[0] #Un tableau d'index avec des éléments non nuls d'un
divided[nonzero_indices] = 1 / a[nonzero_indices] # nonzero_Réécrire uniquement les éléments du tableau en division
print(divided)
# -> [1. 0.5 inf]
Je voulais éviter l'avertissement de seulement 0 division, mais cela semble redondant.
Je veux pouvoir me souvenir et utiliser des méthodes utiles comme numpy.errstate
.