Skip to content

BUG: fixed a bug in multi-level indexing with a Timestamp partial indexer (GH4294) #5088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 2, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/release.rst
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ Bug Fixes
and other reshaping issues.
- Bug in setting with ``ix/loc`` and a mixed int/string index (:issue:`4544`)
- Make sure series-series boolean comparions are label based (:issue:`4947`)
- Bug in multi-level indexing with a Timestamp partial indexer (:issue:`4294`)

pandas 0.12.0
-------------
Expand Down
28 changes: 22 additions & 6 deletions pandas/core/index.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# pylint: disable=E1101,E1103,W0232
import datetime
from functools import partial
from pandas.compat import range, zip, lrange, lzip, u
from pandas import compat
Expand Down Expand Up @@ -2224,16 +2225,20 @@ def get_value(self, series, key):
# Label-based
s = _values_from_object(series)
k = _values_from_object(key)

def _try_mi(k):
# TODO: what if a level contains tuples??
loc = self.get_loc(k)
new_values = series.values[loc]
new_index = self[loc]
new_index = _maybe_droplevels(new_index, k)
return Series(new_values, index=new_index, name=series.name)

try:
return self._engine.get_value(s, k)
except KeyError as e1:
try:
# TODO: what if a level contains tuples??
loc = self.get_loc(key)
new_values = series.values[loc]
new_index = self[loc]
new_index = _maybe_droplevels(new_index, key)
return Series(new_values, index=new_index, name=series.name)
return _try_mi(key)
except KeyError:
pass

Expand All @@ -2250,6 +2255,16 @@ def get_value(self, series, key):
except Exception: # pragma: no cover
raise e1
except TypeError:

# a Timestamp will raise a TypeError in a multi-index
# rather than a KeyError, try it here
if isinstance(key, (datetime.datetime,np.datetime64)) or (
compat.PY3 and isinstance(key, compat.string_types)):
try:
return _try_mi(Timestamp(key))
except:
pass

raise InvalidIndexError(key)

def get_level_values(self, level):
Expand Down Expand Up @@ -2779,6 +2794,7 @@ def reindex(self, target, method=None, level=None, limit=None,
if level is not None:
if method is not None:
raise TypeError('Fill method not supported if level passed')
target = _ensure_index(target)
target, indexer, _ = self._join_level(target, level, how='right',
return_indexers=True)
else:
Expand Down
2 changes: 1 addition & 1 deletion pandas/index.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ cdef class Float64Engine(IndexEngine):
limit=limit)


cdef Py_ssize_t _bin_search(ndarray values, object val):
cdef Py_ssize_t _bin_search(ndarray values, object val) except -1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming that only positive ints and 0 are returned here, is that correct? or more specifically that -1 can't be returned as an index ... if you return -1 explicitly you'll get a runtimerror saying you didn't set the exception handler or soemthing like that .. i don't remember the specific error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep only pos

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the error was not bubbling up..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep ... that's bc of not declaring except -1 ... i answered my own question

cdef:
Py_ssize_t mid, lo = 0, hi = len(values) - 1
object pval
Expand Down
18 changes: 18 additions & 0 deletions pandas/tseries/tests/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -2751,6 +2751,24 @@ def f():
df_multi.loc[('2013-06-19', 'ACCT1', 'ABC')]
self.assertRaises(KeyError, f)

# GH 4294
# partial slice on a series mi
s = pd.DataFrame(randn(1000, 1000), index=pd.date_range('2000-1-1', periods=1000)).stack()

s2 = s[:-1].copy()
expected = s2['2000-1-4']
result = s2[pd.Timestamp('2000-1-4')]
assert_series_equal(result, expected)

result = s[pd.Timestamp('2000-1-4')]
expected = s['2000-1-4']
assert_series_equal(result, expected)

df2 = pd.DataFrame(s)
expected = df2.ix['2000-1-4']
result = df2.ix[pd.Timestamp('2000-1-4')]
assert_frame_equal(result, expected)

def test_date_range_normalize(self):
snap = datetime.today()
n = 50
Expand Down