2016-07-21 106 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'' 

如何檢查datetime64是否爲NaT?我似乎無法從文檔中挖出任何內容。我知道熊貓可以做到這一點,但我寧願不添加一個如此基本的東西的依賴。Numpy:檢查值是否爲NaT

+0

你可以用'np.datetime64(「納特)'實際的比較:'NAT == np.datetime64( 'NaT')'輸出:'正確'。 –

+1

你使用的是1.11.1嗎? NaTs不能再進行比較:https://github.com/numpy/numpy/blob/master/doc/release/1.11.0-notes.rst – user65

+0

我很抱歉,這是我的注意力不集中。 1.現在你可以比較'nat == nat'並且它會返回'True'。 2.正如github所說,在'numpy 1.12.0'中,你仍然可以比較'NaT':'nat!= np.datetime64('NaT')'將返回'True',否則所有的比較涉及NaT將返回False。所以,最後的結論是:首先你需要檢查numpy的版本,然後選擇如何比較'NaT'。 –

回答

7

當您第一次進行比較時,您總會有警告。但與此同時返回比較的結果是正確的:

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 

如果你想取消此警告你可以使用catch_warnings情況管理器:

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 


編輯:對於NAT的一些原因行爲在Numpy版本1.12中的比較沒有改變,所以下一個代碼原來是不一致的。

最後,你可能會檢查numpy的版本來處理,因爲1.12.0版本更改的行爲:

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') 


編輯:作爲 MSeifert提到,numpy的包含自1.13版本 isnat功能。

+0

他們是否忘記將isnull()擴展爲datetime64類型,或者他們是否真的計劃使它無法在1.13中檢查NaT?我明白爲什麼NaT比較被貶低,但我不明白爲什麼沒有其他選擇(除了壓制警告?真的嗎?) – user65

+0

@ user65我想他們可能會做出類似於isnan()像'isnat()'。你爲什麼提到1.13?他們可以在1.12版本中添加它。這意味着爲什麼你現在看到一個警告:NaT比較**不被棄用,它將在版本1.12中被棄用(實際上,它的行爲將會改變)。在版本1.11中,它仍然可以像以前一樣使用。 –

+0

NaN不==NaN。 NaT == NaT?似乎它不,至少基於我的擺弄。所以如果我們用這個測試日期值: *如果thisDate == thisDate:*,並且結果是false,那麼thisDate是NaT。是? – GDB

-1

另一種方式是趕上exeption:

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

這種方法避免了警告,同時保留面向陣列評價。

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

可以pandas.isnull檢查NaT

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

如果你不想使用熊貓你也可以定義自己的功能(部分來自熊貓源獲取):

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 

此正確地識別的NaT值:

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

>>> isnat(np.timedelta64('NAT')) 
True 

,並實現,如果它不是一個datetime或timedelta:

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

在未來有可能在numpy的代碼isnat功能全,他們至少有一個(當前打開的)拉入請求關於它:Link to the PR (NumPy github)

8

由於NumPy版本1。13它包含一個isnat功能:

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

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

它也適用於陣列:

>>> 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

非常簡單和令人驚訝的快:(無numpy的或大熊貓

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

好的,這有點令人討厭,但考慮到圍繞「NaT」的模糊性,它很好地完成了這項工作。

它比較其中任何一個的兩個日期時,可能是Nat如下也是有用:

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

這適用於單個NaT,但不適用於矢量化操作,例如它會爲'np.array(['nat',1,2,3,'nat',5],dtype =' datetime64 [D]')' – MSeifert

+0

同意。由於OP提到了這一點,所以只是想出了不需要依賴的技術。 (儘管它看起來像user65已經在使用numpy,所以isnat將是最好的選擇。) – CodeCabbie