2016-07-21 15 views
21
nat = np.datetime64('NaT') 
nat == nat 
>> FutureWarning: In the future, 'NAT == x' and 'x == NAT' will always be False. 

np.isnan(nat) 
>> TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' 

Wie kann ich überprüfen, ob ein datetime64 NaT ist? Ich kann scheinbar nichts aus den Dokumenten herausgraben. Ich weiß, Pandas können das, aber ich möchte lieber keine Abhängigkeit für etwas so Einfaches hinzufügen.Numpy: Prüfen, ob ein Wert NaT ist

+0

Sie mit 'np.datetime64 vergleichen können ('NaT')' tatsächlich: 'nat == np.datetime64 ('NaT') 'Ausgabe:' True'. –

+1

Verwenden Sie 1.11.1? NaTs können nicht mehr verglichen werden: https://github.com/numpy/numpy/blob/master/doc/release/1.11.0-notes.rst – user65

+0

Ich entschuldige mich, es war meine Unaufmerksamkeit. 1. Jetzt können Sie 'nat == nat' vergleichen und es wird' True' zurückgegeben. 2. Wie im GitHub in 'numpy 1.12.0' gesagt, können Sie' NaT' trotzdem vergleichen: 'nat! = Np.datetime64 ('NaT')' liefert 'True', ansonsten alle Vergleiche NaT wird False zurückgeben. Also, die endgültige Schlussfolgerung: Zuerst müssen Sie die Version von numpy prüfen und dann auswählen, wie Sie 'NaT's vergleichen. –

Antwort

7

Wenn Sie zum ersten Mal einen Vergleich durchführen, haben Sie immer eine Warnung. Aber in der Zwischenzeit zurückVergleichsErgebnis korrekt ist:

import numpy as np  
nat = np.datetime64('NaT') 

def nat_check(nat): 
    return nat == np.datetime64('NaT')  

nat_check(nat) 
Out[4]: FutureWarning: In the future, 'NAT == x' and 'x == NAT' will always be False. 
True 

nat_check(nat) 
Out[5]: True 

Wenn Sie die Warnung zu unterdrücken möchten, können Sie den catch_warnings Kontext-Manager verwenden:

import numpy as np 
import warnings 

nat = np.datetime64('NaT') 

def nat_check(nat): 
    with warnings.catch_warnings(): 
     warnings.simplefilter("ignore") 
     return nat == np.datetime64('NaT')  

nat_check(nat) 
Out[5]: True 


EDIT: Aus irgendeinem Grund Verhalten von NAT Vergleich in Numpy Version 1.12 wurde nicht geändert, daher erwies sich der nächste Code als inkonsistent.

Und schließlich könnten Sie überprüfen numpy Version seit Version 1.12.0 verändertes Verhalten zu handhaben:

def nat_check(nat): 
    if [int(x) for x in np.__version__.split('.')[:-1]] > [1, 11]: 
     return nat != nat 
    with warnings.catch_warnings(): 
     warnings.simplefilter("ignore") 
     return nat == np.datetime64('NaT') 


EDIT: Wie MSeifert erwähnt, Numpy enthält isnat Funktion seit Version 1.13.

+0

Haben sie gerade vergessen, isnull() auf den datetime64-Typ zu erweitern, oder planen sie tatsächlich, es unmöglich zu machen, in 1.13 nach NaT zu suchen? Ich verstehe, warum NaT-Vergleiche abgeschrieben wurden, aber ich kann nicht herausfinden, warum es keine Alternative gibt (außer Warnungen zu unterdrücken? Wirklich?) – user65

+0

@ user65 Ich denke, es ist möglich, dass sie ein Analog von 'isnan()' machen, etwas wie 'isnat()'. Und warum erwähnst du 1,13? Sie können es in Version 1.12 hinzufügen. Und das bedeutet, dass Sie jetzt eine Warnung sehen: NaT-Vergleiche ** ist nicht ** veraltet, ** wird in Version 1.12 ** veraltet sein (sein Verhalten wird sich ändern). In Version 1.11 ist es immer noch wie früher verwendbar. –

+0

NaN nicht == NaN. Ist NaT == NaT? Scheint es nicht, zumindest basierend auf meinem herumspielen. Also, wenn wir einen Datumswert mit diesem testen: * Wenn thisDate == thisDate: * und das Ergebnis falsch ist, dann ist thisDate NaT. Ja? – GDB

-1

Eine andere Möglichkeit wäre es, die exeption zu fangen:

def is_nat(npdatetime): 
    try: 
     npdatetime.strftime('%x') 
     return False 
    except: 
     return True 
1

Dieser Ansatz die Warnungen vermeidet, während das Array orientierte Auswertung zu erhalten.

import numpy as np 
def isnat(x): 
    """ 
    datetime64 analog to isnan. 
    doesn't yet exist in numpy - other ways give warnings 
    and are likely to change. 
    """ 
    return x.astype('i8') == np.datetime64('NaT').astype('i8') 
23

für NaT mit pandas.isnull überprüfen:

>>> import numpy as np 
>>> import pandas as pd 
>>> pd.isnull(np.datetime64('NaT')) 
True 

Wenn Sie Sie (von der Pandas Quelle entnommen werden Teile) eine eigene Funktion definieren können nicht Pandas verwenden möchten auch:

nat_as_integer = np.datetime64('NAT').view('i8') 

def isnat(your_datetime): 
    dtype_string = str(your_datetime.dtype) 
    if 'datetime64' in dtype_string or 'timedelta64' in dtype_string: 
     return your_datetime.view('i8') == nat_as_integer 
    return False # it can't be a NaT if it's not a dateime 

identifiziert korrekt NaT Werte:

und realisiert, wenn es nicht ein Datetime oder Timedelta ist:

>>> isnat(np.timedelta64('NAT').view('i8')) 
False 

In Zukunft könnte es eine isnat -function im numpy Code sein, zumindest haben sie eine (derzeit offen) ziehen Anfrage darüber: Link to the PR (NumPy github)

8

Seit NumPy Version 1.13 enthält eine isnat Funktion:

>>> import numpy as np 
>>> np.__version__ 
'1.13.0' 

>>> np.isnat(np.datetime64('nat')) 
True 

Es funktioniert auch für Arrays:

>>> np.isnat(np.array(['nat', 1, 2, 3, 4, 'nat', 5], dtype='datetime64[D]')) 
array([ True, False, False, False, False, True, False], dtype=bool) 
2

Sehr einfach und überraschend schnell: (ohne numpy oder Pandas)

str(myDate) == 'NaT'   # True if myDate is NaT 

Ok, es ist ein bisschen eklig, aber angesichts der Mehrdeutigkeit um 'NaT' macht es die Arbeit gut.

Es ist auch nützlich, wenn zwei Tage, von denen jeder den Vergleich könnte NaT wie folgt:

str(date1) == str(date1)  # True 
    str(date1) == str(NaT)   # False 
    str(NaT) == str(date1)  # False 

wait for it... 

    str(NaT) == str(Nat)   # True (hooray!) 
+0

Das funktioniert für ein einzelnes NaT, aber nicht in vektorisierten Operationen, zum Beispiel würde es 'False' für' np.array (['nat', 1, 2, 3, 4, 'nat', 5], dtype = ' datetime64 [D] ') ' – MSeifert

+0

Einverstanden. Nur mit Techniken, die keine Abhängigkeiten erfordern, da das OP das erwähnte. (obwohl es so aussieht, als benutze user65 sowieso schon numpy, also wäre isnat der beste weg.) – CodeCabbie

Verwandte Themen