Skip to content

Commit 8dbbf56

Browse files
committed
Merge pull request #5088 from jreback/mi_timestamp
BUG: fixed a bug in multi-level indexing with a Timestamp partial indexer (GH4294)
2 parents 6857482 + ffe4919 commit 8dbbf56

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

doc/source/release.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ Bug Fixes
523523
and other reshaping issues.
524524
- Bug in setting with ``ix/loc`` and a mixed int/string index (:issue:`4544`)
525525
- Make sure series-series boolean comparions are label based (:issue:`4947`)
526+
- Bug in multi-level indexing with a Timestamp partial indexer (:issue:`4294`)
526527

527528
pandas 0.12.0
528529
-------------

pandas/core/index.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# pylint: disable=E1101,E1103,W0232
2+
import datetime
23
from functools import partial
34
from pandas.compat import range, zip, lrange, lzip, u
45
from pandas import compat
@@ -2224,16 +2225,20 @@ def get_value(self, series, key):
22242225
# Label-based
22252226
s = _values_from_object(series)
22262227
k = _values_from_object(key)
2228+
2229+
def _try_mi(k):
2230+
# TODO: what if a level contains tuples??
2231+
loc = self.get_loc(k)
2232+
new_values = series.values[loc]
2233+
new_index = self[loc]
2234+
new_index = _maybe_droplevels(new_index, k)
2235+
return Series(new_values, index=new_index, name=series.name)
2236+
22272237
try:
22282238
return self._engine.get_value(s, k)
22292239
except KeyError as e1:
22302240
try:
2231-
# TODO: what if a level contains tuples??
2232-
loc = self.get_loc(key)
2233-
new_values = series.values[loc]
2234-
new_index = self[loc]
2235-
new_index = _maybe_droplevels(new_index, key)
2236-
return Series(new_values, index=new_index, name=series.name)
2241+
return _try_mi(key)
22372242
except KeyError:
22382243
pass
22392244

@@ -2250,6 +2255,16 @@ def get_value(self, series, key):
22502255
except Exception: # pragma: no cover
22512256
raise e1
22522257
except TypeError:
2258+
2259+
# a Timestamp will raise a TypeError in a multi-index
2260+
# rather than a KeyError, try it here
2261+
if isinstance(key, (datetime.datetime,np.datetime64)) or (
2262+
compat.PY3 and isinstance(key, compat.string_types)):
2263+
try:
2264+
return _try_mi(Timestamp(key))
2265+
except:
2266+
pass
2267+
22532268
raise InvalidIndexError(key)
22542269

22552270
def get_level_values(self, level):
@@ -2779,6 +2794,7 @@ def reindex(self, target, method=None, level=None, limit=None,
27792794
if level is not None:
27802795
if method is not None:
27812796
raise TypeError('Fill method not supported if level passed')
2797+
target = _ensure_index(target)
27822798
target, indexer, _ = self._join_level(target, level, how='right',
27832799
return_indexers=True)
27842800
else:

pandas/index.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ cdef class Float64Engine(IndexEngine):
408408
limit=limit)
409409

410410

411-
cdef Py_ssize_t _bin_search(ndarray values, object val):
411+
cdef Py_ssize_t _bin_search(ndarray values, object val) except -1:
412412
cdef:
413413
Py_ssize_t mid, lo = 0, hi = len(values) - 1
414414
object pval

pandas/tseries/tests/test_timeseries.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,24 @@ def f():
27512751
df_multi.loc[('2013-06-19', 'ACCT1', 'ABC')]
27522752
self.assertRaises(KeyError, f)
27532753

2754+
# GH 4294
2755+
# partial slice on a series mi
2756+
s = pd.DataFrame(randn(1000, 1000), index=pd.date_range('2000-1-1', periods=1000)).stack()
2757+
2758+
s2 = s[:-1].copy()
2759+
expected = s2['2000-1-4']
2760+
result = s2[pd.Timestamp('2000-1-4')]
2761+
assert_series_equal(result, expected)
2762+
2763+
result = s[pd.Timestamp('2000-1-4')]
2764+
expected = s['2000-1-4']
2765+
assert_series_equal(result, expected)
2766+
2767+
df2 = pd.DataFrame(s)
2768+
expected = df2.ix['2000-1-4']
2769+
result = df2.ix[pd.Timestamp('2000-1-4')]
2770+
assert_frame_equal(result, expected)
2771+
27542772
def test_date_range_normalize(self):
27552773
snap = datetime.today()
27562774
n = 50

0 commit comments

Comments
 (0)