it-swarm.com.de

Was könnte die Ursache für 'ungültiger Wert in less_equal' in numpy sein?

Ich habe eine RuntimeWarning erlebt 

 RuntimeWarning: invalid value encountered in less_equal

Generiert durch diese Codezeile von mir:

center_dists[j] <= center_dists[i]

Sowohl center_dists[j] als auch center_dists[i] sind numpy-Arrays

Was könnte die Ursache für diese Warnung sein?

20
Alex Gao

Dies ist höchstwahrscheinlich auf einen np.nan irgendwo in den beteiligten Eingaben zurückzuführen. Ein Beispiel davon ist unten gezeigt -

In [1]: A = np.array([4, 2, 1])

In [2]: B = np.array([2, 2, np.nan])

In [3]: A<=B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: array([False,  True, False], dtype=bool)

Für alle diese Vergleiche mit np.nan würde False ausgegeben werden. Bestätigen wir es für einen broadcasted Vergleich. Hier ist ein Beispiel -

In [1]: A = np.array([4, 2, 1])

In [2]: B = np.array([2, 2, np.nan])

In [3]: A[:,None] <= B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: 
array([[False, False, False],
       [ True,  True, False],
       [ True,  True, False]], dtype=bool)

Beachten Sie die dritte Spalte in der Ausgabe, die dem Vergleich mit dem dritten Element np.nan in B entspricht und das alle False-Werte ergibt.

22
Divakar

Numpy dtypes sind so streng. Es erzeugt also kein Array wie np.array([False, True, np.nan]), sondern gibt array([ 0., 1., nan]) zurück, das ein float -Array ist.

Wenn Sie versuchen, ein Bool-Array wie folgt zu ändern:

x= np.array([False, False, False])
x[0] = 5

wird erneut ausgeführt array([ True, False, False]) ... wow

Aber ich denke, 5>np.nan Kann nicht False sein, es sollte nan sein, False würde bedeuten, dass ein Datenvergleich durchgeführt wurde und das Ergebnis wie 3>5, Was ich für eine Katastrophe halte. Numpy erzeugt Daten, die wir eigentlich nicht haben. Wenn es nan hätte zurückgeben können, dann könnten wir es mit Leichtigkeit handhaben.

Also habe ich versucht, das Verhalten mit einer Funktion zu ändern.

def ngrater(x, y):
    with np.errstate(invalid='ignore'):
        c=x>y
        c=c.astype(np.object)
        c[np.isnan(x)] = np.nan
        c[np.isnan(y)] = np.nan
        return c
a = np.array([np.nan,1,2,3,4,5, np.nan, np.nan, np.nan]) #9 elements
b = np.array([0,1,-2,-3,-4,-5, -5, -5, -5]) #9 elements

ngrater(a,b)

gibt zurück: array([nan, False, True, True, True, True, nan, nan, nan], dtype=object)

Aber ich denke, die gesamte Speicherstruktur wird auf diese Weise verändert. Anstatt einen Speicherblock mit einheitlichen Einheiten zu erhalten, wird ein Zeigerblock erzeugt, in dem sich die realen Daten an einer anderen Stelle befinden. Die Funktion arbeitet also möglicherweise langsamer und das ist wahrscheinlich der Grund, warum Numpy das nicht tut. Wir brauchen einen superBool dtype, der auch np.nan Enthält, oder wir müssen nur float-Arrays verwenden +1:True, -1:False, nan:nan

0

Dies liegt an Nan Werten im Datenrahmen, was für DF völlig in Ordnung ist.

In Pycharm hat das wie ein Zauber für mich gewirkt:

import warnings

warnings.simplefilter(action = "ignore", category = RuntimeWarning)
0
Revanth M

Als Folgemaßnahme zu Divakars Antwort und Kommentar zur Unterdrückung der RuntimeWarning ist es sicherer, sie nur local mit with np.errstate() ( docs ) zu unterdrücken: Es ist ratsam, beim Vergleich mit np.nan allgemein gewarnt zu werden Geben Sie False ab und ignorieren Sie die Warnung nur, wenn dies wirklich beabsichtigt ist. Hier zum Beispiel des OP:

with np.errstate(invalid='ignore'):
  center_dists[j] <= center_dists[i]

Beim Beenden des with-Blocks wird die Fehlerbehandlung auf den vorherigen Wert zurückgesetzt.

Anstelle von invalid value encountered können Sie auch alle Fehler ignorieren, indem Sie all='ignore' übergeben. Interessanterweise fehlt dies in der kwargs in den Dokumenten für np.errstate(), nicht aber in den für np.seterr() . (Scheint wie ein kleiner Fehler in den np.errstate() docs.)

0
Ulrich Stern