Skip to content

Commit 984aa8e

Browse files
committed
Merge branch 'datetime-index-insert-non-datetimes' of https://github.com/jtratner/pandas into jtratner-datetime-index-insert-non-datetimes
Conflicts: doc/source/release.rst
2 parents b5535b9 + 3204652 commit 984aa8e

File tree

7 files changed

+41
-10
lines changed

7 files changed

+41
-10
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ Bug Fixes
147147
(:issue:`6043`)
148148
- Regression in ``.get(None)`` indexing from 0.12 (:issue:`5652`)
149149
- Subtle ``iloc`` indexing bug, surfaced in (:issue:`6059`)
150+
- Bug with insert of strings into DatetimeIndex (:issue:`5818`)
150151

151152
pandas 0.13.0
152153
-------------

pandas/core/indexing.py

-1
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,6 @@ def _safe_append_to_index(index, key):
14231423

14241424
# raise here as this is basically an unsafe operation and we want
14251425
# it to be obvious that you are doing something wrong
1426-
14271426
raise ValueError("unsafe appending to index of type {0} with a key "
14281427
"{1}".format(index.__class__.__name__, key))
14291428

pandas/sparse/tests/test_sparse.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1084,8 +1084,10 @@ def test_icol(self):
10841084

10851085
def test_set_value(self):
10861086

1087-
# this is invalid because it is not a valid type for this index
1088-
self.assertRaises(ValueError, self.frame.set_value, 'foobar', 'B', 1.5)
1087+
# ok as the index gets conver to object
1088+
frame = self.frame.copy()
1089+
res = frame.set_value('foobar', 'B', 1.5)
1090+
self.assert_(res.index.dtype == 'object')
10891091

10901092
res = self.frame
10911093
res.index = res.index.astype(object)

pandas/tests/test_frame.py

+13
Original file line numberDiff line numberDiff line change
@@ -10968,6 +10968,19 @@ def test_reset_index_multiindex_col(self):
1096810968
['a', 'mean', 'median', 'mean']])
1096910969
assert_frame_equal(rs, xp)
1097010970

10971+
def test_reset_index_with_datetimeindex_cols(self):
10972+
# GH5818
10973+
#
10974+
df = pd.DataFrame([[1, 2], [3, 4]],
10975+
columns=pd.date_range('1/1/2013', '1/2/2013'),
10976+
index=['A', 'B'])
10977+
10978+
result = df.reset_index()
10979+
expected = pd.DataFrame([['A', 1, 2], ['B', 3, 4]],
10980+
columns=['index', datetime(2013, 1, 1),
10981+
datetime(2013, 1, 2)])
10982+
assert_frame_equal(result, expected)
10983+
1097110984
#----------------------------------------------------------------------
1097210985
# Tests to cope with refactored internals
1097310986
def test_as_matrix_numeric_cols(self):

pandas/tests/test_indexing.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1809,15 +1809,13 @@ def test_partial_set_invalid(self):
18091809

18101810
df = tm.makeTimeDataFrame()
18111811

1812+
# don't allow not string inserts
18121813
def f():
18131814
df.loc[100.0, :] = df.ix[0]
18141815
self.assertRaises(ValueError, f)
18151816
def f():
18161817
df.loc[100,:] = df.ix[0]
18171818
self.assertRaises(ValueError, f)
1818-
def f():
1819-
df.loc['a',:] = df.ix[0]
1820-
self.assertRaises(ValueError, f)
18211819

18221820
def f():
18231821
df.ix[100.0, :] = df.ix[0]
@@ -1826,6 +1824,9 @@ def f():
18261824
df.ix[100,:] = df.ix[0]
18271825
self.assertRaises(ValueError, f)
18281826

1827+
# allow object conversion here
1828+
df.loc['a',:] = df.ix[0]
1829+
18291830
def test_partial_set_empty(self):
18301831

18311832
# GH5226

pandas/tseries/index.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -1525,18 +1525,26 @@ def insert(self, loc, item):
15251525
----------
15261526
loc : int
15271527
item : object
1528+
if not either a Python datetime or a numpy integer-like, returned
1529+
Index dtype will be object rather than datetime.
15281530
15291531
Returns
15301532
-------
15311533
new_index : Index
15321534
"""
15331535
if isinstance(item, datetime):
15341536
item = _to_m8(item, tz=self.tz)
1535-
1536-
new_index = np.concatenate((self[:loc].asi8,
1537+
try:
1538+
new_index = np.concatenate((self[:loc].asi8,
15371539
[item.view(np.int64)],
15381540
self[loc:].asi8))
1539-
return DatetimeIndex(new_index, freq='infer')
1541+
return DatetimeIndex(new_index, freq='infer')
1542+
except (AttributeError, TypeError):
1543+
1544+
# fall back to object index
1545+
if isinstance(item,compat.string_types):
1546+
return self.asobject.insert(loc, item)
1547+
raise TypeError("cannot insert DatetimeIndex with incompatible label")
15401548

15411549
def delete(self, loc):
15421550
"""
@@ -1577,7 +1585,7 @@ def tz_convert(self, tz):
15771585
def tz_localize(self, tz, infer_dst=False):
15781586
"""
15791587
Localize tz-naive DatetimeIndex to given time zone (using pytz)
1580-
1588+
15811589
Parameters
15821590
----------
15831591
tz : string or pytz.timezone

pandas/tseries/tests/test_timeseries.py

+7
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,13 @@ def test_insert(self):
20382038
'2000-01-02'])
20392039
self.assert_(result.equals(exp))
20402040

2041+
# insertion of non-datetime should coerce to object index
2042+
result = idx.insert(1, 'inserted')
2043+
expected = Index([datetime(2000, 1, 4), 'inserted', datetime(2000, 1, 1),
2044+
datetime(2000, 1, 2)])
2045+
self.assert_(not isinstance(result, DatetimeIndex))
2046+
tm.assert_index_equal(result, expected)
2047+
20412048
idx = date_range('1/1/2000', periods=3, freq='M')
20422049
result = idx.insert(3, datetime(2000, 4, 30))
20432050
self.assert_(result.freqstr == 'M')

0 commit comments

Comments
 (0)