141

I'm trying to test if one of my variables is pd.NaT. I know it is NaT, and still it won't pass the test. As an example, the following code prints nothing :

a=pd.NaT

if a == pd.NaT:
    print("a not NaT")

Does anyone have a clue ? Is there a way to effectively test if a is NaT?

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
Clément F
  • 3,535
  • 6
  • 18
  • 26
  • 7
    `pd.isnull` also works for NaTs. – cs95 Mar 22 '18 at 17:50
  • 1
    `pandas` and `numpy` follow the standard that `NaN` does not equate to itself. so even if you typed `a == a` you would get `False` – ALollz Mar 22 '18 at 17:54
  • 4
    Voting to reopen because `pandas.NaT` isn't actually a NumPy `NaT`, and it behaves differently in equality and `numpy.isnat` checks. – user2357112 Mar 22 '18 at 18:01
  • @ALollz: NumPy doesn't actually do that yet; there's a `FutureWarning` saying they plan to, but for now, `numpy.datetime64('NaT') == numpy.datetime64('NaT')`. – user2357112 Mar 22 '18 at 18:21
  • *Related*: [Numpy: Checking if a value is NaT](https://stackoverflow.com/questions/38509538/numpy-checking-if-a-value-is-nat) – jpp Mar 22 '18 at 18:22
  • @user2357112 Thanks for the heads up! Good to know. – ALollz Mar 22 '18 at 18:48

5 Answers5

211

Pandas NaT behaves like a floating-point NaN, in that it's not equal to itself. Instead, you can use pandas.isnull:

In [21]: pandas.isnull(pandas.NaT)
Out[21]: True

This also returns True for None and NaN.

Technically, you could also check for Pandas NaT with x != x, following a common pattern used for floating-point NaN. However, this is likely to cause issues with NumPy NaTs, which look very similar and represent the same concept, but are actually a different type with different behavior:

In [29]: x = pandas.NaT

In [30]: y = numpy.datetime64('NaT')

In [31]: x != x
Out[31]: True

In [32]: y != y
/home/i850228/.local/lib/python3.6/site-packages/IPython/__main__.py:1: FutureWarning: In the future, NAT != NAT will be True rather than False.
  # encoding: utf-8
Out[32]: False

numpy.isnat, the function to check for NumPy NaT, also fails with a Pandas NaT:

In [33]: numpy.isnat(pandas.NaT)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-33-39a66bbf6513> in <module>()
----> 1 numpy.isnat(pandas.NaT)

TypeError: ufunc 'isnat' is only defined for datetime and timedelta.

pandas.isnull works for both Pandas and NumPy NaTs, so it's probably the way to go:

In [34]: pandas.isnull(pandas.NaT)
Out[34]: True

In [35]: pandas.isnull(numpy.datetime64('NaT'))
Out[35]: True
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Note that `pandas.isnull()` is an alias to `pandas.isna()` – Dima Chubarov Jul 21 '22 at 09:03
  • @DmitriChubarov there must be something different. I used this pattern: `df.apply(lambda x: ... if x.time.isna() else ..., axis=1)`. In that case the following error is thrown: `AttributeError: 'NaTType' object has no attribute 'isna'`. But if I use `pd. isnull(x.time)`, it behaves as expected – MikeB2019x Sep 23 '22 at 14:14
  • @MikeB2019x you should be able to use `pd.isna(x.time)` – Dima Chubarov Sep 24 '22 at 12:18
27
pd.NaT is pd.NaT

True

this works for me.

Long Bu
  • 513
  • 4
  • 9
16

You can also use pandas.isna() for pandas.NaT, numpy.nan or None:

import pandas as pd
import numpy as np

x = (pd.NaT, np.nan, None)
[pd.isna(i) for i in x]

Output:
[True, True, True]
Lukas
  • 2,034
  • 19
  • 27
9

If it's in a Series (e.g. DataFrame column) you can also use .isna():

pd.Series(pd.NaT).isna()
# 0    True
# dtype: bool
Max Ghenis
  • 14,783
  • 16
  • 84
  • 132
  • Not sure this is true. I had a df and was using "df.apply(lambda x: ... if x.time.isna() else ..., axis=1)". In that case the following error was thrown: "AttributeError: 'NaTType' object has no attribute 'isna'". – MikeB2019x Sep 23 '22 at 14:09
1

This is what works for me

>>> a = pandas.NaT
>>> type(a) == pandas._libs.tslibs.nattype.NaTType
>>> True
Helton Wernik
  • 185
  • 2
  • 3