Python Numpy:检查值是否为NaT

Python Numpy:检查值是否为NaT,python,numpy,pandas,Python,Numpy,Pandas,如何检查datetime64是否为NaT?我似乎无法从这些文件中找到任何东西。我知道熊猫可以做到这一点,但我不想为如此基本的东西添加依赖项。简介:这个答案是在Numpy版本为1.11,NAT比较行为自版本1.12以来发生变化的时候写的。显然情况并非如此,答案的第二部分错了。答案的第一部分可能不适用于numpy的新版本。请确保您已在下面查看了MSeifert的答案。 当你第一次进行比较时,你总是有一个警告。但同时返回的比较结果是正确的: nat = np.datetime64('NaT') na

如何检查datetime64是否为NaT?我似乎无法从这些文件中找到任何东西。我知道熊猫可以做到这一点,但我不想为如此基本的东西添加依赖项。

简介:这个答案是在Numpy版本为1.11,NAT比较行为自版本1.12以来发生变化的时候写的。显然情况并非如此,答案的第二部分错了。答案的第一部分可能不适用于numpy的新版本。请确保您已在下面查看了MSeifert的答案。
当你第一次进行比较时,你总是有一个警告。但同时返回的比较结果是正确的:

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''
如果要抑制警告,可以使用上下文管理器:

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

编辑:由于某种原因,Numpy版本1.12中NAT比较的行为没有改变,因此下一个代码结果不一致

最后,您可能会检查numpy版本以处理自版本1.12.0以来的更改行为:

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


编辑:如前所述,Numpy自1.13版起就包含了
isnat
功能。

另一种方法是捕获例外:

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

这种方法避免了警告,同时保留了面向数组的求值

def is_nat(npdatetime):
    try:
        npdatetime.strftime('%x')
        return False
    except:
        return True
可以使用以下工具检查
NaT

如果您不想使用pandas,还可以定义自己的功能(部件取自pandas源):

这将正确识别NaT值:

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
并意识到如果不是datetime或timedelta:

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

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


将来numpy代码中可能会有一个
isnat
-函数,至少他们有一个(当前打开的)拉取请求:

,因为numpy版本1.13包含一个函数:

>>> isnat(np.timedelta64('NAT').view('i8'))
False
它也适用于阵列:

>>> import numpy as np
>>> np.isnat(np.datetime64('nat'))
True

非常简单而且出人意料地快速:(没有努比或熊猫

好吧,这有点令人讨厌,但考虑到“NaT”的模糊性,它做得很好

在比较两个日期(其中一个可能是NaT)时,它也很有用,如下所示:

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

您可以与
np.datetime64('NaT')
实际比较:
NaT==np.datetime64('NaT')
输出:
True
。是否使用1.11.1?纳茨再也无法与之相比了:我很抱歉,这是我的疏忽。1.现在您可以比较
nat==nat
,它将返回
True
。2.正如github中所说,在
numpy 1.12.0
中,您仍然可以比较
NaT
NaT!=np.datetime64('NaT')
将返回
True
,否则所有涉及NaT的比较将返回False。因此,最后的结论是:首先需要检查numpy的版本,然后选择如何比较
NaT
。您能否提供一个如何检查值是否为NaT的示例?无论使用哪种操作员,我都会收到警告。你能接受瓦迪姆的回答吗?未来的警告是,NumPy开发人员计划进行更改,以使答案不再有效。他们只是忘记了将isnull()扩展到datetime64类型,还是他们真的计划在1.13中不可能检查NaT?我理解为什么NaT比较被贬低,但我不明白为什么没有其他选择(除了抑制警告?真的吗?@user65我想他们可能会模拟
isnan()
,类似于
isnat()
)。你为什么提到1.13?他们可以将其添加到1.12版中。这也就是为什么现在您会看到一条警告:NaT比较并没有被弃用,它将在1.12版中被弃用(实际上,它的行为将改变)。在版本1.11中,它仍然像以前一样可用。NaN不==NaN。NaT==NaT吗?似乎没有,至少从我的摆弄来看。因此,如果我们测试一个日期值:如果thisDate==thisDate:,并且结果为false,那么thisDate就是NaT。是吗?根据我的经验,CodeCabbie的回答是正确的,我不确定NaT模糊性是否是一个可能导致这一点不正确的问题。如果任何歧义都会导致情况并非如此,该怎么办?@TTeaTie
pandas
不用于回答。这适用于单个NaT,但不适用于矢量化操作,例如,它将为
np.array(['NaT',1,2,3,4,'NaT',5],dtype='datetime64[D]')提供
。刚刚提出的技术不需要依赖性,因为OP提到了这一点。(尽管看起来user65已经在使用numpy了,所以isnat将是最好的方式。)观察,这似乎无关紧要:你使用
NaT
NaT
。再次出现的是
pd.datetime64()
对这两个函数都给出了相同的结果,但对
'
None也有相同的结果。尽管如此,似乎一个答案的一致性会让读者不那么困惑。
>>> import numpy as np
>>> 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)
    str( myDate ) == 'NaT'            # True if myDate is 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!)