Numpy:检查值是不是为 NaT
Posted
技术标签:
【中文标题】Numpy:检查值是不是为 NaT【英文标题】:Numpy: Checking if a value is NaTNumpy:检查值是否为 NaT 【发布时间】:2016-11-25 08:37:32 【问题描述】: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?我似乎无法从文档中挖掘出任何东西。我知道 Pandas 可以做到,但我不想为这么基本的东西添加依赖项。
【问题讨论】:
你可以和np.datetime64('NaT')
比较其实:nat == np.datetime64('NaT')
输出:True
。
您使用的是 1.11.1 吗?无法再比较 NaT:github.com/numpy/numpy/blob/master/doc/release/1.11.0-notes.rst
我很抱歉,这是我的疏忽。 1. 现在你可以比较nat == nat
,它会返回True
。 2. 正如github中所说,在numpy 1.12.0
中你仍然可以比较NaT
:nat != np.datetime64('NaT')
将返回True
,否则所有涉及NaT的比较都将返回False。所以,最后的结论:首先你需要检查numpy的版本,然后选择如何比较NaT
的。
您能否提供一个如何检查值是否为 NaT 的示例?无论使用什么运算符,我仍然会收到警告。
你能不接受瓦迪姆的回答吗? FutureWarning 表示 NumPy 开发人员计划进行更改,以便答案不再有效。
【参考方案1】:
简介:这个答案是在 Numpy 是 1.11 版的时候写的,并且 NAT 比较的行为应该从 1.12 版开始改变。显然情况并非如此,答案的第二部分变得错误。答案的第一部分可能不适用于新版本的 numpy。请确保您已在下面查看 MSeifert 的答案。
当您第一次进行比较时,您总是有一个警告。但同时返回的比较结果是正确的:
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
编辑:由于某种原因,Numpy 1.12 版中的 NAT 比较行为没有改变,因此下一个代码结果不一致。
最后,您可以检查 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 包含
isnat
函数,因为版本 1.13。
【讨论】:
他们是否只是忘记将 isnull() 扩展为 datetime64 类型,或者他们是否真的计划在 1.13 中无法检查 NaT?我理解为什么 NaT 比较已被贬值,但我不明白为什么没有其他选择(除了禁止警告?真的吗?) @user65 我猜他们可能会模拟isnan()
,类似于isnat()
。为什么你提到 1.13?他们可以在 1.12 版本中添加它。这意味着您现在看到警告的原因:NaT 比较 未 被弃用,它在 1.12 版中将被弃用(实际上,它的行为会改变)。在 1.11 版本中,它仍然可以像以前一样使用。
NaN 不 == NaN。 NaT == NaT 吗?似乎没有,至少基于我的摆弄。所以如果我们用这个来测试一个日期值:if thisDate == thisDate:,结果是假的,那么 thisDate 就是 NaT。是吗?
CodeCabbie 的回答根据我的经验是正确的,我不确定 NaT 歧义是否是一个可能导致这不正确的问题。如果有任何歧义会导致情况并非如此呢?
@TTeaTie pandas
未在答案中使用。【参考方案2】:
另一种方法是捕获异常:
def is_nat(npdatetime):
try:
npdatetime.strftime('%x')
return False
except:
return True
【讨论】:
【参考方案3】:这种方法避免了警告,同时保留了面向数组的评估。
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')
【讨论】:
【参考方案4】:pandas 可以检查 NaT
和 pandas.isnull
:
>>> import numpy as np
>>> import pandas as pd
>>> pd.isnull(np.datetime64('NaT'))
True
如果你不想使用 pandas 也可以定义自己的函数(部分取自 pandas 源):
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
并意识到它是否不是日期时间或时间增量:
>>> isnat(np.timedelta64('NAT').view('i8'))
False
将来在 numpy 代码中可能会有一个isnat
-function,至少他们有一个(当前打开的)关于它的拉取请求:Link to the PR (NumPy github)
【讨论】:
观察,这似乎无关紧要:您使用NaT
和NAT
。同样,pd.datetime64()
似乎对两者都吐出相同的结果,但对于''
和None
也是如此。尽管如此,答案的一致性似乎不会让读者感到困惑。【参考方案5】:
从 NumPy 1.13 版开始,它包含一个isnat
函数:
>>> 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)
【讨论】:
【参考方案6】:非常简单而且出人意料地快速:(没有numpy或pandas)
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!)
【讨论】:
这适用于单个 NaT,但不适用于矢量化操作,例如它会为np.array(['nat', 1, 2, 3, 4, 'nat', 5], dtype='datetime64[D]')
提供 False
同意。由于OP提到了这一点,因此只是提出了不需要依赖项的技术。 (虽然看起来 user65 已经在使用 numpy,所以 isnat 将是最好的选择。)以上是关于Numpy:检查值是不是为 NaT的主要内容,如果未能解决你的问题,请参考以下文章