ENH: indexing support for reversed is_monotonic · Issue #7860 · pandas-dev/pandas (original) (raw)
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