[PYTHON] [Numpy] Vermeiden Sie die Warnung vor 0 Teilung

Ich war ratlos, als ich das Programm selbst schrieb, also werde ich es als Memo aufschreiben. Wenn Sie eine bessere Lösung kennen, weisen Sie bitte darauf hin.

※Umgebung

0 Division von Numpy

Ich bekomme einen "ZeroDivisionError", wenn ich eine normale 0-Division in Python mache.

python


try:
    divided = 1 / 0
except ZeroDivisionError as e:
    print(f'ZeroDivisionError: {e}')

# -> ZeroDivisionError: division by zero

Wenn Sie dagegen mit numpy durch 0 teilen, tritt "RuntimeWarning" auf, das Ergebnis wird jedoch ausgegeben, ohne die Verarbeitung zu stoppen.

python


import numpy as np

divided = 1 / np.array(0)
print(devided)
# -> inf
# -> RuntimeWarning: divide by zero encountered in true_divide

Das Ergebnis der Berechnung von "1 / np.array (0)" ist das Objekt "numpy.inf", das die Unendlichkeit mit numpy darstellt. Es gibt eine Warnung, aber es stoppt den Prozess nicht, so dass es sich auf halbem Weg anfühlt. Vielleicht bleibt es dem Benutzer überlassen zu sagen: "Ich kann es berechnen, aber ich gebe Ihnen eine Warnung. Ich überlasse es Ihnen." Überlegen wir uns also, was zu tun ist, wenn Sie den Prozess stoppen möchten und wenn Sie den Prozess zulassen und die Warnung ignorieren.

Verwenden Sie warnings.simplefilter

Sie können warnings.simplefilter verwenden, um RuntimeWarning zu einer Ausnahme zu machen oder sie zu ignorieren.

--Wenn Sie es als Ausnahme behandeln und die Verarbeitung beenden möchten

python


import warnings
import numpy as np
warnings.simplefilter('error', category=RuntimeWarning)  #Legen Sie die Laufzeitwarnung als Ausnahme fest

a = np.array(0)  #Variablen, von denen nicht erwartet wird, dass sie 0 enthalten
divided = 1 / a
print(divided)

# -> RuntimeWarning: divide by zero encountered in true_divide
# divided = 1 /Die Verarbeitung stoppt bei a und druckt(divided)Wird nicht ausgeführt

--Wenn Sie Berechnungen zulassen und Warnungen ignorieren möchten

python


import warnings
import numpy as np
warnings.simplefilter('ignore', category=RuntimeWarning)  #Stellen Sie die Laufzeitwarnung so ein, dass sie ignoriert wird

a = np.array(0)  #Variablen, die 0 enthalten können
divided = 1 / a
print(divided)

# -> inf
#Es wird keine Warnung ausgegeben und die Verarbeitung wird fortgesetzt

Zu diesem Zeitpunkt wird das Steuerelement jedoch auf eine andere Laufzeit als die 0-Division angewendet, sodass das Risiko besteht, dass der Fehler nicht erfasst werden kann, insbesondere wenn er ignoriert wird. Also denke ich über eine andere Methode nach

Verwenden Sie numpy.seteer

(Als Antwort auf den Kommentar habe ich "numpy.seteer" hinzugefügt.) Sie können numpy.seteer verwenden, um die Feinsteuerung von Warning einzustellen.

python


import numpy as np
np.seterr(divide='ignore')  #Ignoriere nur die Laufzeitwarnung von 0 Division

a = np.array(0)
divided = 1 / a
print(divided)

# -> inf

Jetzt können Sie die Steuerung nur zur 0-Division hinzufügen. Die Komplexität des Importierens von Warnungen wurde ebenfalls beseitigt. In diesem Fall gilt dieses Steuerelement jedoch für den gesamten Quellcode. Wenn möglich, möchte ich den Kontrollumfang minimieren. Sie können das Steuerelement wechseln, indem Sie vor und nach der Division "numpy.seterr" schreiben. Beachten Sie jedoch eine intelligentere Beschreibung.

Verwenden Sie numpy.errstate

(Dies ist auch der Teil, der aus den Kommentaren hinzugefügt wurde)

Mit numpy.errstate ist die Steuerung durch den Kontextmanager möglich.

python


import numpy as np

a = np.array(0) 
with np.errstate(divide='ignore'):  #Wenden Sie die Kontrolle nur innerhalb des Bereichs an
    divided = 1 / a
print(divided)
# -> inf

divided = 1 / a  #Laufzeitwarnung tritt auf, weil sie nicht vernachlässigt werden kann
# -> RuntimeWarning: divide by zero encountered in true_divide

Dies reduziert den Umfang von Kontrolländerungen und ergänzt Fehler, die durch (nicht zulässige) Abteilungen an anderer Stelle verursacht werden.

In diesem Beispiel haben wir aus Gründen der Übersichtlichkeit die Aufteilung von Zahlen betrachtet, aber Sie können auch die Aufteilung des Arrays steuern.

python


import numpy as np

a = np.array([1, 2, 0]) 
with np.errstate(divide='ignore'):  #Wenden Sie die Kontrolle nur innerhalb des Bereichs an
    divided = 1 / a
print(divided)
# -> [1.  0.5 inf]

Wenn Sie eine Zahl teilen möchten, können Sie einfach eine if-Anweisung schreiben, dies ist jedoch für ein Array schwierig. Daher halte ich diese Steuermethode für nützlich.

Bonus

Zuerst kannte ich "numpy.errstate" nicht und dachte darüber nach, wie ich es wie folgt schreiben sollte.

python


import numpy as np

a = np.array([1, 2, 0])
divided = np.full(len(a), np.inf)  #Alle Elemente sind np.Machen Sie ein Array von inf
nonzero_indices = np.where(a != 0)[0]  #Ein Array von Indizes mit Nicht-Null-Elementen von a
divided[nonzero_indices] = 1 / a[nonzero_indices]  # nonzero_Schreiben Sie nur die Elemente des Arrays in Division um

print(divided)
# -> [1.  0.5 inf]

Ich wollte nur die Warnung vor einer 0-Division vermeiden, aber sie scheint überflüssig zu sein. Ich möchte mich an nützliche Methoden wie "numpy.errstate" erinnern und diese anwenden können.

Recommended Posts

[Numpy] Vermeiden Sie die Warnung vor 0 Teilung
Vermeiden Sie die Warnung [ungültiger Wert in true_divide], wenn Sie durch Null geteilt werden