Aus Interesse: float("NaN")

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ich weise Variablen schon mal den Wert NaN zu, wenn ich z. B. noch keinen Wert berechnet habe. Jetzt wollte ich auf diesen Wert testen und habe u. a. folgendes gelernt:

Code: Alles auswählen

>>> a = float("NaN")
>>> if a == float("NaN"):
    print(True)
>>> if float("NaN") == float("NaN"):
    print("Ja")
>>> import math
>>> math.isnan(a)
True
Kann mir jemand sagen, warum das mit dem == nicht funktioniert? Das entspricht nicht meiner Erwartung, die sich auf Erfahrungen mit None stützt.
Sirius3
User
Beiträge: 18261
Registriert: Sonntag 21. Oktober 2012, 17:20

@pixewakb: NaN ist der falsche Wert für Variablen ohne Wert, dafür gibt es None. NaN bedeutet "keine existierende Zahl". Und es ist eben Konvention, dass zwei nicht existierende Zahlen auch nicht gleich sein können. Steht so auch bei Wikipedia: https://en.wikipedia.org/wiki/NaN.
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ich zitiere mal aus dem Wikipedia-Artikel: "and NaNs may be used to represent missing values in computations."

Die Diskussion mit None und NaN hatten wir schon, damals hatte mir BlackJack, wenn ich mich richtig erinnere, von None weggeraten und zu NaN geraten. Im konkreten Fall muss ich Mittelwerte berechnen und das Problem ist, dass es dann ja Werte gibt, die nicht berechnet werden können (gleitender Mittelwert, Zeitraum 2:

Code: Alles auswählen

values = [8, 4, 6, 4]
mw     = [x, 6, 5, 5]
Wie ich das x sinnvoll "ersetze" oder "markiere", darum geht es mir eigentlich. NaN hat für mich den Vorteil, dass es in einer HTML-Tabelle nicht zu leeren bzw. fehlenden Zellen führt!?

BTW: Ganz vielen Dank für deine Rückmeldung - wenn es so definiert ist, dann ist das eine sehr gute Sache, das zu wissen. Vielen, lieben Dank!
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Ob es sinnvoll ist NaN zu nutzen oder nicht hängt vom Algorithmus ab und welches Verhalten du haben möchtest.
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Dann sag ich mal: Szenario ist Mittelwerte berechnen und ich muss irgendwie kenntlich machen, dass ich für bestimmte Werte noch keinen Mittelwert berechnen konnte.

Code: Alles auswählen

>>> a = [None, 4, 4, 4, 4]
>>> print(sum(a) / len(a))
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    print(sum(a) / len(a))
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
>>> a = [float("NaN"), 4, 4, 4, 4]
>>> print(sum(a) / len(a))
nan
Ich habe float("NaN") seinerzeit auf Anraten von BlackJack eingeführt und es löst einige Probleme. Die eigentlichen Probleme fange ich durch Platzhalter ab. Was wäre denn die sinnvolle Lösung (state of the art)? Von eigenen Entwicklungen versuche ich momentan eigentlich weg zu kommen...
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Da ein gleitender Mittelwert benachbarter Elemente einer Sequenz nur sinnvoll sein kann, wenn es auch benachbarte Elemente gibt, würde ich einfach sowas machen, wobei das Ergebnis ein Element weniger besitzt, als die Ausgangssequenz:

Code: Alles auswählen

>>> from itertools import tee
>>> def pairwise(seq):
...     a, b = tee(seq)
...     next(b)
...     return zip(a, b)
... 
>>> list(pairwise([1, 2, 3, 4]))
[(1, 2), (2, 3), (3, 4)]
>>> [(x + y) // 2 for x, y in pairwise([8, 4, 6, 4])]
[6, 5, 5]
Schau dir mal in der Doku zu itertools die Recipes an.
In specifications, Murphy's Law supersedes Ohm's.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sowohl None als auch NaN koennen sinnvoll sein. Du musst halt nur math.isnan benutzen, wenn du dich fuer letzteres entscheidest. Genauso wie du sonst "is None" benutzen musst - ein reiner boolscher Vergleich ala

if zahl: ...

reicht dir ja eh nicht, denn dein Mittelwert koennte ja durch Zufall 0 sein, und dann geht das in die Hose.

Ich kenne die Diskussion von dir und BJ nicht, aber intuitiv wuerde ich eher auf None als auf NaN setzen. Der einzige Grund fuer mich das anders zu machen waere, wenn du eine Verarbeitungskette hast, die mit NaN klarkommt, aber nicht mit None, und zB aus Berechnungen mit NaN dann einfach wieder NaN zurueckliefert. Und du dir dadurch eine Fallunterscheidung sparst.
Antworten