Skip to content

Commit 892634a

Browse files
stephenwlinchanghiskhan
authored andcommitted
BUG: Slicing and setitem inconsistent with getitem using DateTimeIndex with timezone
1 parent 6ba858c commit 892634a

File tree

2 files changed

+94
-22
lines changed

2 files changed

+94
-22
lines changed

pandas/tests/test_series.py

+67-1
Original file line numberDiff line numberDiff line change
@@ -2544,13 +2544,75 @@ def test_asof(self):
25442544
d = self.ts.index[0] - datetools.bday
25452545
self.assert_(np.isnan(self.ts.asof(d)))
25462546

2547+
def test_getitem_setitem_datetimeindex(self):
2548+
from pandas import date_range
2549+
N = 50
2550+
# testing with timezone, GH #2785
2551+
rng = date_range('1/1/1990', periods=N, freq='H', tz='US/Eastern')
2552+
ts = Series(np.random.randn(N), index=rng)
2553+
2554+
result = ts["1990-01-01 04:00:00"]
2555+
expected = ts[4]
2556+
self.assert_(result == expected)
2557+
2558+
result = ts.copy()
2559+
result["1990-01-01 04:00:00"] = 0
2560+
result["1990-01-01 04:00:00"] = ts[4]
2561+
assert_series_equal(result, ts)
2562+
2563+
result = ts["1990-01-01 04:00:00":"1990-01-01 07:00:00"]
2564+
expected = ts[4:8]
2565+
assert_series_equal(result, expected)
2566+
2567+
result = ts.copy()
2568+
result["1990-01-01 04:00:00":"1990-01-01 07:00:00"] = 0
2569+
result["1990-01-01 04:00:00":"1990-01-01 07:00:00"] = ts[4:8]
2570+
assert_series_equal(result, ts)
2571+
2572+
lb = "1990-01-01 04:00:00"
2573+
rb = "1990-01-01 07:00:00"
2574+
result = ts[(ts.index >= lb) & (ts.index <= rb)]
2575+
expected = ts[4:8]
2576+
assert_series_equal(result, expected)
2577+
2578+
result = ts[ts.index[4]]
2579+
expected = ts[4]
2580+
self.assert_(result == expected)
2581+
2582+
result = ts[ts.index[4:8]]
2583+
expected = ts[4:8]
2584+
assert_series_equal(result, expected)
2585+
2586+
result = ts.copy()
2587+
result[ts.index[4:8]] = 0
2588+
result[4:8] = ts[4:8]
2589+
assert_series_equal(result, ts)
2590+
2591+
# also test partial date slicing
2592+
result = ts["1990-01-02"]
2593+
expected = ts[24:48]
2594+
assert_series_equal(result, expected)
2595+
2596+
result = ts.copy()
2597+
result["1990-01-02"] = 0
2598+
result["1990-01-02"] = ts[24:48]
2599+
assert_series_equal(result, ts)
2600+
25472601
def test_getitem_setitem_periodindex(self):
25482602
from pandas import period_range, Period
2549-
# array or list or dates
25502603
N = 50
25512604
rng = period_range('1/1/1990', periods=N, freq='H')
25522605
ts = Series(np.random.randn(N), index=rng)
25532606

2607+
result = ts["1990-01-01 04"]
2608+
expected = ts[4]
2609+
self.assert_(result == expected)
2610+
2611+
result = ts.copy()
2612+
result["1990-01-01 04"] = 0
2613+
result["1990-01-01 04"] = ts[4]
2614+
assert_series_equal(result, ts)
2615+
25542616
result = ts["1990-01-01 04":"1990-01-01 07"]
25552617
expected = ts[4:8]
25562618
assert_series_equal(result, expected)
@@ -2567,6 +2629,10 @@ def test_getitem_setitem_periodindex(self):
25672629
assert_series_equal(result, expected)
25682630

25692631
# GH 2782
2632+
result = ts[ts.index[4]]
2633+
expected = ts[4]
2634+
self.assert_(result == expected)
2635+
25702636
result = ts[ts.index[4:8]]
25712637
expected = ts[4:8]
25722638
assert_series_equal(result, expected)

pandas/tseries/index.py

+27-21
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def wrapper(self, other):
7171
other = _to_m8(other)
7272
elif isinstance(other, list):
7373
other = DatetimeIndex(other)
74+
elif isinstance(other, basestring):
75+
other = _to_m8(Timestamp(other, tz=self.tz))
7476
elif not isinstance(other, np.ndarray):
7577
other = _ensure_datetime64(other)
7678
result = func(other)
@@ -1042,34 +1044,36 @@ def _partial_date_slice(self, reso, parsed):
10421044
'time series.')
10431045

10441046
if reso == 'year':
1045-
t1 = Timestamp(datetime(parsed.year, 1, 1))
1046-
t2 = Timestamp(datetime(parsed.year, 12, 31))
1047+
t1 = Timestamp(datetime(parsed.year, 1, 1), tz=self.tz)
1048+
t2 = Timestamp(datetime(parsed.year, 12, 31), tz=self.tz)
10471049
elif reso == 'month':
10481050
d = tslib.monthrange(parsed.year, parsed.month)[1]
1049-
t1 = Timestamp(datetime(parsed.year, parsed.month, 1))
1050-
t2 = Timestamp(datetime(parsed.year, parsed.month, d))
1051+
t1 = Timestamp(datetime(parsed.year, parsed.month, 1), tz=self.tz)
1052+
t2 = Timestamp(datetime(parsed.year, parsed.month, d), tz=self.tz)
10511053
elif reso == 'quarter':
10521054
qe = (((parsed.month - 1) + 2) % 12) + 1 # two months ahead
10531055
d = tslib.monthrange(parsed.year, qe)[1] # at end of month
1054-
t1 = Timestamp(datetime(parsed.year, parsed.month, 1))
1055-
t2 = Timestamp(datetime(parsed.year, qe, d))
1056+
t1 = Timestamp(datetime(parsed.year, parsed.month, 1), tz=self.tz)
1057+
t2 = Timestamp(datetime(parsed.year, qe, d), tz=self.tz)
10561058
elif reso == 'day' and self._resolution < Resolution.RESO_DAY:
10571059
st = datetime(parsed.year, parsed.month, parsed.day)
1058-
t1 = Timestamp(st)
1060+
t1 = Timestamp(st, tz=self.tz)
10591061
t2 = st + offsets.Day()
1060-
t2 = Timestamp(Timestamp(t2).value - 1)
1062+
t2 = Timestamp(Timestamp(t2, tz=self.tz).value - 1)
10611063
elif (reso == 'hour' and
10621064
self._resolution < Resolution.RESO_HR):
10631065
st = datetime(parsed.year, parsed.month, parsed.day,
10641066
hour=parsed.hour)
1065-
t1 = Timestamp(st)
1066-
t2 = Timestamp(Timestamp(st + offsets.Hour()).value - 1)
1067+
t1 = Timestamp(st, tz=self.tz)
1068+
t2 = Timestamp(Timestamp(st + offsets.Hour(),
1069+
tz=self.tz).value - 1)
10671070
elif (reso == 'minute' and
10681071
self._resolution < Resolution.RESO_MIN):
10691072
st = datetime(parsed.year, parsed.month, parsed.day,
10701073
hour=parsed.hour, minute=parsed.minute)
1071-
t1 = Timestamp(st)
1072-
t2 = Timestamp(Timestamp(st + offsets.Minute()).value - 1)
1074+
t1 = Timestamp(st, tz=self.tz)
1075+
t2 = Timestamp(Timestamp(st + offsets.Minute(),
1076+
tz=self.tz).value - 1)
10731077
else:
10741078
raise KeyError
10751079

@@ -1091,7 +1095,6 @@ def get_value(self, series, key):
10911095
try:
10921096
return Index.get_value(self, series, key)
10931097
except KeyError:
1094-
10951098
try:
10961099
loc = self._get_string_slice(key)
10971100
return series[loc]
@@ -1102,11 +1105,11 @@ def get_value(self, series, key):
11021105
locs = self.indexer_at_time(key)
11031106
return series.take(locs)
11041107

1105-
if isinstance(key, basestring):
1106-
stamp = Timestamp(key, tz=self.tz)
1107-
else:
1108-
stamp = Timestamp(key)
11091108
try:
1109+
if isinstance(key, basestring):
1110+
stamp = Timestamp(key, tz=self.tz)
1111+
else:
1112+
stamp = Timestamp(key)
11101113
return self._engine.get_value(series, stamp)
11111114
except KeyError:
11121115
raise KeyError(stamp)
@@ -1131,15 +1134,18 @@ def get_loc(self, key):
11311134
return self.indexer_at_time(key)
11321135

11331136
try:
1134-
return self._engine.get_loc(Timestamp(key))
1137+
if isinstance(key, basestring):
1138+
stamp = Timestamp(key, tz=self.tz)
1139+
else:
1140+
stamp = Timestamp(key)
1141+
return self._engine.get_loc(stamp)
11351142
except (KeyError, ValueError):
11361143
raise KeyError(key)
11371144

11381145
def _get_string_slice(self, key):
11391146
freq = getattr(self, 'freqstr',
11401147
getattr(self, 'inferred_freq', None))
1141-
asdt, parsed, reso = parse_time_string(key, freq)
1142-
key = asdt
1148+
_, parsed, reso = parse_time_string(key, freq)
11431149
loc = self._partial_date_slice(reso, parsed)
11441150
return loc
11451151

@@ -1617,7 +1623,7 @@ def _to_m8(key):
16171623
'''
16181624
Timestamp-like => dt64
16191625
'''
1620-
if not isinstance(key, datetime):
1626+
if not isinstance(key, (Timestamp, datetime)):
16211627
# this also converts strings
16221628
key = Timestamp(key)
16231629

0 commit comments

Comments
 (0)