Repository: pandas-dev/pandas

Issue:
ENH: indexing support for reversed is_monotonic
conceptually not hard (and you can look at a the slices to figure this out, e.g. if start >= end or start>last_endpoint, you can just do a reversed is_monotonic), to avoid a perf hit I think, then just reverse the searching operations for slices would need to do `is_monotonic_decreasing` here : https://github.com/pydata/pandas/blob/master/pandas/core/index.py#L1764

Hello,

I am working with spectral data, which for various spectral units such as
wavenumber, is often presented with decreasing spectral values along the
index.  For example:

http://www.chemguide.co.uk/analysis/ir/irpropanone.GIF

In my dataframe, the index is stored in descending order (eg 500, 499,
498... 2, 1); however, when I try to slice using .ix[]; it becomes
impossible, giving me a long key error.

Likewise, df.plot() is sorting the xvalues from low to high, so I need to
reverse the plot axis after the fact.  Not really a big deal, but wondered
if there's a better workaround.

Any suggestions?

**Note: This behavior works fine for int64 index:**

```
#Create dataframe and reverse index
x = DataFrame(np.random.randn(50,50))
x.index = x.index[::-1]

#Slice 30-10
x.ix[30:10, ::]
```

But fails for float index

```
x = DataFrame(np.random.randn(50,50), 
                  index=np.linspace(0,50))
x.index = x.index[::-1]

x.ix[30.0:10.0, ::]
```

With error:

```
 ---------------------------------------------------------------------------
 KeyError                                  Traceback (most recent call last)
 <ipython-input-68-1af3b9a79d3d> in <module>()
      11 x.index = x.index[::-1]
      12 
 ---> 13 x.ix[30.0:10.0, ::]
      14 

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.pyc in __getitem__(self, key)
      67                 pass
      68 
 ---> 69             return self._getitem_tuple(key)
      70         else:
      71             return self._getitem_axis(key, axis=0)

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.pyc in _getitem_tuple(self, tup)
     673                 continue
     674 
 --> 675             retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
     676 
     677         return retval

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.pyc in _getitem_axis(self, key, axis, validate_iterable)
     859         labels = self.obj._get_axis(axis)
     860         if isinstance(key, slice):
 --> 861             return self._get_slice_axis(key, axis=axis)
     862         elif _is_list_like(key) and not (isinstance(key, tuple) and
     863                                          isinstance(labels, MultiIndex)):

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.pyc in _get_slice_axis(self, slice_obj, axis)
    1106         if not _need_slice(slice_obj):
    1107             return obj
 -> 1108         indexer = self._convert_slice_indexer(slice_obj, axis)
    1109 
    1110         if isinstance(indexer, slice):

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.pyc in _convert_slice_indexer(self, key, axis)
     161         # if we are accessing via lowered dim, use the last dim
     162         ax = self.obj._get_axis(min(axis, self.ndim - 1))
 --> 163         return ax._convert_slice_indexer(key, typ=self.name)
     164 
     165     def _has_valid_setitem_indexer(self, indexer):

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in _convert_slice_indexer(self, key, typ)
    2027 
    2028         # translate to locations
 -> 2029         return self.slice_indexer(key.start, key.stop, key.step)
    2030 
    2031     def get_value(self, series, key):

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in slice_indexer(self, start, end, step)
    1704         This function assumes that the data is sorted, so use at your own peril
    1705         """
 -> 1706         start_slice, end_slice = self.slice_locs(start, end)
    1707 
    1708         # return a slice

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in slice_locs(self, start, end)
    1777 
    1778         start_slice = _get_slice(0, offset=0, search_side='left',
 -> 1779                                  slice_property='start', search_value=start)
    1780         end_slice = _get_slice(len(self), offset=1, search_side='right',
    1781                                slice_property='stop', search_value=end)

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in _get_slice(starting_value, offset, search_side, slice_property, search_value)
    1746 
    1747             try:
 -> 1748                 slc = self.get_loc(search_value)
    1749 
    1750                 if not is_unique:

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in get_loc(self, key)
    2091         except (TypeError, NotImplementedError):
    2092             pass
 -> 2093         return super(Float64Index, self).get_loc(key)
    2094 
    2095     @property

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/index.pyc in get_loc(self, key)
    1179         loc : int if unique index, possibly slice or mask if not
    1180         """
 -> 1181         return self._engine.get_loc(_values_from_object(key))
    1182 
    1183     def get_value(self, series, key):

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/index.so in pandas.index.IndexEngine.get_loc (pandas/index.c:3354)()

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/index.so in pandas.index.IndexEngine.get_loc (pandas/index.c:3234)()

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/hashtable.so in pandas.hashtable.Float64HashTable.get_item (pandas/hashtable.c:9018)()

 /home/glue/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/hashtable.so in pandas.hashtable.Float64HashTable.get_item (pandas/hashtable.c:8962)()

 KeyError: 30.0
```



Discussion:
always `pd.show_versions()`

you can use:

`x[(x.index>10.0)&(x.index<30.0)]`

its not clear what:

`x.ix[30.0:10.0,:]` actually would mean for a reversed index as neither point is in the index. I supposed it _could_ mean the above, but would have to think about that.

For an integer index, its clear, because the end-points are included.

@cpcloud 
@jorisvandenbossche 

Sorry, here's `show_verions()`:

In [4]: pd.show_versions()

## INSTALLED VERSIONS

commit: None
python: 2.7.6.final.0
python-bits: 64
OS: Linux
OS-release: 2.6.32-62-generic
machine: x86_64
processor: 
byteorder: little
LC_ALL: None
LANG: en_US.utf8

pandas: 0.14.1
nose: 1.3.0
Cython: None
numpy: 1.8.0
scipy: 0.14.0
statsmodels: 0.5.0
IPython: 3.0.0-dev
sphinx: None
patsy: 0.2.1
scikits.timeseries: None
dateutil: 2.2
pytz: 2014.4
bottleneck: None
tables: None
numexpr: None
matplotlib: 1.3.1
openpyxl: 2.0.3
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
httplib2: None
apiclient: None
rpy2: None
sqlalchemy: None
pymysql: None

Thanks for the solution.  I'll use it for sure, but the ix behavior should work right?  This is such a common index type in spectral data, I'd hate to require a seperate slice call for this use case.  Although, if it's not likely to be changed in the future, I could probably just add my own slice functions that bury this under the hood unbeknownst to users.  What do you recommend?

pls review docs here as well: http://pandas.pydata.org/pandas-docs/stable/indexing.html#float64index

I think this was not implemented because its not 'cheap'. In the sense that it _would_ work if you _knew_ that the index was monotonic, but reversed (iow would need to have a `is_monotonic_increasing` and `is_monotonic_decreasing` and then could just reverse the searching operators.

Well, that makes sense, thanks.  I'll either make my own slice wrapper, or
raise a warning to users if they try to slice reversed index data.

On Mon, Jul 28, 2014 at 3:33 PM, jreback notifications@github.com wrote:

> pls review docs here as well:
> http://pandas.pydata.org/pandas-docs/stable/indexing.html#float64index
> 
> I think this was not implemented because its not 'cheap'. In the sense
> that it _would_ work if you _knew_ that the index was monotonic, but
> reversed (iow would need to have a is_monotonic_increasing and
> is_monotonic_decreasing and then could just reverse the searching
> operators.
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/pydata/pandas/issues/7860#issuecomment-50387218.

## 

Adam Hughes
Physics Ph.D Candidate
George Washington University

we'll put it on the enhancement list. if you are interested in implemented, step up!

Alright, thanks.  I would take a crack, but really feel like I don't know the pandas code base well enough to guarantee my solution will do more good than harm.  

I'm considering taking a crack at this, but there's one edge case I would like to clarify first. In particular: how do we want to handle slices with mis-matched ordering, e.g., `x.loc[10:30]` for an descending index or `x.loc[30:10]` for an ascending index.

Keeping track of whether an index is descending or ascending is one of those details that's nice to keep track of for the user, so it would be nice if these "just work" by switching `start`/`stop` in these cases. It seems like this would be handy for cases where the index is generally monotonic but can go either direction, e.g., as is the case for a number of physical variables.

Can anyone think of unfortunate consequences to this sort of interchanging?

@shoyer you can add to the `is_monotonic_float64` et. all in `generated.pyx` and just return say -1 if is negative monotonic, then it would 'keep track' internally (just as is_monotonic does now, but for increasing).

Then I think you could easily just swap the start stop in those caes.

@jreback Excellent, I'll take a look. I'd like this to work for `Int64Index`, too, for the sake of consistency, although the typical case is floating point data.

you can do for all types - just change the template

I just wanted to point out that I did use @jreback suggestion for the boolean experssion and just put that into my **getitem**() indexer calls somewhere, and haven't encountered any problems since.  This is probably a hacky solution, but for my use case, works fine.

Can I ask how monotonicity is determined?  Are all values inspected, or just the start and final?   And does `is_monotonic_float64` already exist, or is this what is being proposed to be put in?  It would help me if I had access to this attribute as well for when we do plotting.  In fact, that might be an issue to consider.  Matplotlib will try to plot from low to high values I believe, and I had to actually reverse the xlimits on calls to df.plot().  Unless my memory is mixed up...

Here is where `is_monotonic` is defined: https://github.com/pydata/pandas/blob/c7bfb4e16411516ca9108af95013bc3400ba38ad/pandas/src/generate_code.py#L542

This should be an easy fix to extend to identify descending indexes. It does indeed check all values (when necessary).

The advantage to using slice syntax is it uses numpy.ndarray views instead of making copies, so it's much faster. Also, various scientific file formats (e.g., netCDF, HDF5, OpenDAP) support reading slices directly but are much slower or have more limited support for array indexing. The later will be handy for [xray](https://github.com/xray/xray), and it will get that for free when I add this to pandas.


Resolving patch:
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -1461,7 +1461,7 @@ def xs(self, key, axis=0, level=None, copy=None, drop_level=True):
                             name=self.index[loc])
 
         else:
-            result = self[loc]
+            result = self.iloc[loc]
             result.index = new_index
 
         # this could be a view
diff --git a/pandas/core/index.py b/pandas/core/index.py
--- a/pandas/core/index.py
+++ b/pandas/core/index.py
@@ -573,8 +573,22 @@ def _mpl_repr(self):
 
     @property
     def is_monotonic(self):
-        """ return if the index has monotonic (only equaly or increasing) values """
-        return self._engine.is_monotonic
+        """ alias for is_monotonic_increasing (deprecated) """
+        return self._engine.is_monotonic_increasing
+
+    @property
+    def is_monotonic_increasing(self):
+        """ return if the index is monotonic increasing (only equal or
+        increasing) values
+        """
+        return self._engine.is_monotonic_increasing
+
+    @property
+    def is_monotonic_decreasing(self):
+        """ return if the index is monotonic decreasing (only equal or
+        decreasing values
+        """
+        return self._engine.is_monotonic_decreasing
 
     def is_lexsorted_for_tuple(self, tup):
         return True
@@ -1988,16 +2002,12 @@ def _get_slice(starting_value, offset, search_side, slice_property,
                     slc += offset
 
             except KeyError:
-                if self.is_monotonic:
-
-                    # we are duplicated but non-unique
-                    # so if we have an indexer then we are done
-                    # else search for it (GH 7523)
-                    if not is_unique and is_integer(search_value):
-                        slc = search_value
-                    else:
-                        slc = self.searchsorted(search_value,
-                                                side=search_side)
+                if self.is_monotonic_increasing:
+                    slc = self.searchsorted(search_value, side=search_side)
+                elif self.is_monotonic_decreasing:
+                    search_side = 'right' if search_side == 'left' else 'left'
+                    slc = len(self) - self[::-1].searchsorted(search_value,
+                                                              side=search_side)
                 else:
                     raise
             return slc
@@ -2431,10 +2441,13 @@ def __contains__(self, other):
     def get_loc(self, key):
         try:
             if np.all(np.isnan(key)):
+                nan_idxs = self._nan_idxs
                 try:
-                    return self._nan_idxs.item()
-                except ValueError:
-                    return self._nan_idxs
+                    return nan_idxs.item()
+                except (ValueError, IndexError):
+                    # should only need to catch ValueError here but on numpy
+                    # 1.7 .item() can raise IndexError when NaNs are present
+                    return nan_idxs
         except (TypeError, NotImplementedError):
             pass
         return super(Float64Index, self).get_loc(key)
diff --git a/pandas/src/generate_code.py b/pandas/src/generate_code.py
--- a/pandas/src/generate_code.py
+++ b/pandas/src/generate_code.py
@@ -539,31 +539,51 @@ def diff_2d_%(name)s(ndarray[%(c_type)s, ndim=2] arr,
 
 is_monotonic_template = """@cython.boundscheck(False)
 @cython.wraparound(False)
-def is_monotonic_%(name)s(ndarray[%(c_type)s] arr):
+def is_monotonic_%(name)s(ndarray[%(c_type)s] arr, bint timelike):
     '''
     Returns
     -------
-    is_monotonic, is_unique
+    is_monotonic_inc, is_monotonic_dec, is_unique
     '''
     cdef:
         Py_ssize_t i, n
         %(c_type)s prev, cur
         bint is_unique = 1
+        bint is_monotonic_inc = 1
+        bint is_monotonic_dec = 1
 
     n = len(arr)
 
-    if n < 2:
-        return True, True
+    if n == 1:
+        if arr[0] != arr[0] or (timelike and arr[0] == iNaT):
+            # single value is NaN
+            return False, False, True
+        else:
+            return True, True, True
+    elif n < 2:
+        return True, True, True
+
+    if timelike and arr[0] == iNaT:
+        return False, False, None
 
     prev = arr[0]
     for i in range(1, n):
         cur = arr[i]
+        if timelike and cur == iNaT:
+            return False, False, None
         if cur < prev:
-            return False, None
+            is_monotonic_inc = 0
+        elif cur > prev:
+            is_monotonic_dec = 0
         elif cur == prev:
             is_unique = 0
+        else:
+            # cur or prev is NaN
+            return False, False, None
+        if not is_monotonic_inc and not is_monotonic_dec:
+            return False, False, None
         prev = cur
-    return True, is_unique
+    return is_monotonic_inc, is_monotonic_dec, is_unique
 """
 
 map_indices_template = """@cython.wraparound(False)


Test patch:
diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py
--- a/pandas/tests/test_frame.py
+++ b/pandas/tests/test_frame.py
@@ -866,7 +866,7 @@ def test_getitem_setitem_integer_slice_keyerrors(self):
         assert_frame_equal(result2, expected)
 
         # non-monotonic, raise KeyError
-        df2 = df[::-1]
+        df2 = df.iloc[lrange(5) + lrange(5, 10)[::-1]]
         self.assertRaises(KeyError, df2.ix.__getitem__, slice(3, 11))
         self.assertRaises(KeyError, df2.ix.__setitem__, slice(3, 11), 0)
 
diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py
--- a/pandas/tests/test_index.py
+++ b/pandas/tests/test_index.py
@@ -848,33 +848,56 @@ def test_get_indexer(self):
         assert_almost_equal(r1, rbfill1)
 
     def test_slice_locs(self):
-        idx = Index([0, 1, 2, 5, 6, 7, 9, 10])
-        n = len(idx)
-
-        self.assertEqual(idx.slice_locs(start=2), (2, n))
-        self.assertEqual(idx.slice_locs(start=3), (3, n))
-        self.assertEqual(idx.slice_locs(3, 8), (3, 6))
-        self.assertEqual(idx.slice_locs(5, 10), (3, n))
-        self.assertEqual(idx.slice_locs(end=8), (0, 6))
-        self.assertEqual(idx.slice_locs(end=9), (0, 7))
-
-        idx2 = idx[::-1]
-        self.assertRaises(KeyError, idx2.slice_locs, 8, 2)
-        self.assertRaises(KeyError, idx2.slice_locs, 7, 3)
+        for dtype in [int, float]:
+            idx = Index(np.array([0, 1, 2, 5, 6, 7, 9, 10], dtype=dtype))
+            n = len(idx)
+
+            self.assertEqual(idx.slice_locs(start=2), (2, n))
+            self.assertEqual(idx.slice_locs(start=3), (3, n))
+            self.assertEqual(idx.slice_locs(3, 8), (3, 6))
+            self.assertEqual(idx.slice_locs(5, 10), (3, n))
+            self.assertEqual(idx.slice_locs(5.0, 10.0), (3, n))
+            self.assertEqual(idx.slice_locs(4.5, 10.5), (3, 8))
+            self.assertEqual(idx.slice_locs(end=8), (0, 6))
+            self.assertEqual(idx.slice_locs(end=9), (0, 7))
+
+            idx2 = idx[::-1]
+            self.assertEqual(idx2.slice_locs(8, 2), (2, 6))
+            self.assertEqual(idx2.slice_locs(8.5, 1.5), (2, 6))
+            self.assertEqual(idx2.slice_locs(7, 3), (2, 5))
+            self.assertEqual(idx2.slice_locs(10.5, -1), (0, n))
 
     def test_slice_locs_dup(self):
         idx = Index(['a', 'a', 'b', 'c', 'd', 'd'])
-        rs = idx.slice_locs('a', 'd')
-        self.assertEqual(rs, (0, 6))
-
-        rs = idx.slice_locs(end='d')
-        self.assertEqual(rs, (0, 6))
+        self.assertEqual(idx.slice_locs('a', 'd'), (0, 6))
+        self.assertEqual(idx.slice_locs(end='d'), (0, 6))
+        self.assertEqual(idx.slice_locs('a', 'c'), (0, 4))
+        self.assertEqual(idx.slice_locs('b', 'd'), (2, 6))
 
-        rs = idx.slice_locs('a', 'c')
-        self.assertEqual(rs, (0, 4))
-
-        rs = idx.slice_locs('b', 'd')
-        self.assertEqual(rs, (2, 6))
+        idx2 = idx[::-1]
+        self.assertEqual(idx2.slice_locs('d', 'a'), (0, 6))
+        self.assertEqual(idx2.slice_locs(end='a'), (0, 6))
+        self.assertEqual(idx2.slice_locs('d', 'b'), (0, 4))
+        self.assertEqual(idx2.slice_locs('c', 'a'), (2, 6))
+
+        for dtype in [int, float]:
+            idx = Index(np.array([10, 12, 12, 14], dtype=dtype))
+            self.assertEqual(idx.slice_locs(12, 12), (1, 3))
+            self.assertEqual(idx.slice_locs(11, 13), (1, 3))
+
+            idx2 = idx[::-1]
+            self.assertEqual(idx2.slice_locs(12, 12), (1, 3))
+            self.assertEqual(idx2.slice_locs(13, 11), (1, 3))
+
+    def test_slice_locs_na(self):
+        idx = Index([np.nan, 1, 2])
+        self.assertRaises(KeyError, idx.slice_locs, start=1.5)
+        self.assertRaises(KeyError, idx.slice_locs, end=1.5)
+        self.assertEqual(idx.slice_locs(1), (1, 3))
+        self.assertEqual(idx.slice_locs(np.nan), (0, 3))
+
+        idx = Index([np.nan, np.nan, 1, 2])
+        self.assertRaises(KeyError, idx.slice_locs, np.nan)
 
     def test_drop(self):
         n = len(self.strIndex)
@@ -922,6 +945,7 @@ def test_tuple_union_bug(self):
     def test_is_monotonic_incomparable(self):
         index = Index([5, datetime.now(), 7])
         self.assertFalse(index.is_monotonic)
+        self.assertFalse(index.is_monotonic_decreasing)
 
     def test_get_set_value(self):
         values = np.random.randn(100)
@@ -1286,6 +1310,15 @@ def test_equals(self):
         i2 = Float64Index([1.0,np.nan])
         self.assertTrue(i.equals(i2))
 
+    def test_get_loc_na(self):
+        idx = Float64Index([np.nan, 1, 2])
+        self.assertEqual(idx.get_loc(1), 1)
+        self.assertEqual(idx.get_loc(np.nan), 0)
+
+        idx = Float64Index([np.nan, 1, np.nan])
+        self.assertEqual(idx.get_loc(1), 1)
+        self.assertRaises(KeyError, idx.slice_locs, np.nan)
+
     def test_contains_nans(self):
         i = Float64Index([1.0, 2.0, np.nan])
         self.assertTrue(np.nan in i)
@@ -1403,9 +1436,31 @@ def test_dtype(self):
 
     def test_is_monotonic(self):
         self.assertTrue(self.index.is_monotonic)
+        self.assertTrue(self.index.is_monotonic_increasing)
+        self.assertFalse(self.index.is_monotonic_decreasing)
 
         index = Int64Index([4, 3, 2, 1])
         self.assertFalse(index.is_monotonic)
+        self.assertTrue(index.is_monotonic_decreasing)
+
+        index = Int64Index([1])
+        self.assertTrue(index.is_monotonic)
+        self.assertTrue(index.is_monotonic_increasing)
+        self.assertTrue(index.is_monotonic_decreasing)
+
+    def test_is_monotonic_na(self):
+        examples = [Index([np.nan]),
+                    Index([np.nan, 1]),
+                    Index([1, 2, np.nan]),
+                    Index(['a', 'b', np.nan]),
+                    pd.to_datetime(['NaT']),
+                    pd.to_datetime(['NaT', '2000-01-01']),
+                    pd.to_datetime(['2000-01-01', 'NaT', '2000-01-02']),
+                    pd.to_timedelta(['1 day', 'NaT']),
+                   ]
+        for index in examples:
+            self.assertFalse(index.is_monotonic_increasing)
+            self.assertFalse(index.is_monotonic_decreasing)
 
     def test_equals(self):
         same_values = Index(self.index, dtype=object)
diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py
--- a/pandas/tests/test_series.py
+++ b/pandas/tests/test_series.py
@@ -1544,7 +1544,7 @@ def test_ix_getitem(self):
     def test_ix_getitem_not_monotonic(self):
         d1, d2 = self.ts.index[[5, 15]]
 
-        ts2 = self.ts[::2][::-1]
+        ts2 = self.ts[::2][[1, 2, 0]]
 
         self.assertRaises(KeyError, ts2.ix.__getitem__, slice(d1, d2))
         self.assertRaises(KeyError, ts2.ix.__setitem__, slice(d1, d2), 0)
@@ -1570,7 +1570,7 @@ def test_ix_getitem_setitem_integer_slice_keyerrors(self):
         assert_series_equal(result2, expected)
 
         # non-monotonic, raise KeyError
-        s2 = s[::-1]
+        s2 = s.iloc[lrange(5) + lrange(5, 10)[::-1]]
         self.assertRaises(KeyError, s2.ix.__getitem__, slice(3, 11))
         self.assertRaises(KeyError, s2.ix.__setitem__, slice(3, 11), 0)
 
diff --git a/pandas/tseries/tests/test_base.py b/pandas/tseries/tests/test_base.py
--- a/pandas/tseries/tests/test_base.py
+++ b/pandas/tseries/tests/test_base.py
@@ -85,7 +85,7 @@ def test_asobject_tolist(self):
     def test_minmax(self):
         for tz in self.tz:
             # monotonic
-            idx1 = pd.DatetimeIndex([pd.NaT, '2011-01-01', '2011-01-02',
+            idx1 = pd.DatetimeIndex(['2011-01-01', '2011-01-02',
                                      '2011-01-03'], tz=tz)
             self.assertTrue(idx1.is_monotonic)
 
@@ -305,7 +305,7 @@ def test_asobject_tolist(self):
     def test_minmax(self):
 
         # monotonic
-        idx1 = TimedeltaIndex(['nat', '1 days', '2 days', '3 days'])
+        idx1 = TimedeltaIndex(['1 days', '2 days', '3 days'])
         self.assertTrue(idx1.is_monotonic)
 
         # non-monotonic