Skip to content

Commit bea8101

Browse files
committed
BUG: Make DateTimeIndex copy datetime64[ns] data on copy=True
1 parent 3320727 commit bea8101

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

pandas/indexes/base.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,33 @@ def _shallow_copy_with_infer(self, values=None, **kwargs):
376376
pass
377377
return Index(values, **attributes)
378378

379+
def _deepcopy_if_needed(self, orig, copy=False):
380+
"""
381+
.. versionadded:: 0.18.2
382+
383+
Make a copy of self if data coincides (in memory) with orig.
384+
Subclasses should override this if self._base is not an ndarray.
385+
386+
Parameters
387+
----------
388+
orig : ndarray
389+
other ndarray to compare self._data against
390+
copy : boolean, default False
391+
when False, do not run any check, just return self
392+
393+
Returns
394+
-------
395+
A copy of self if needed, otherwise self : Index
396+
"""
397+
if copy:
398+
# Retrieve the "base objects", i.e. the original memory allocations
399+
orig = orig if orig.base is None else orig.base
400+
new = self._data if self._data.base is None else self._data.base
401+
if orig is new:
402+
return self.copy(deep=True)
403+
404+
return self
405+
379406
def _update_inplace(self, result, **kwargs):
380407
# guard when called from IndexOpsMixin
381408
raise TypeError("Index can't be updated inplace")

pandas/tseries/index.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ def __new__(cls, data=None,
225225
verify_integrity=True, normalize=False,
226226
closed=None, ambiguous='raise', dtype=None, **kwargs):
227227

228+
# This allows to later ensure that the 'copy' parameter is honored:
229+
if isinstance(data, Index):
230+
ref_to_data = data._data
231+
else:
232+
ref_to_data = data
233+
228234
if name is None and hasattr(data, 'name'):
229235
name = data.name
230236

@@ -305,7 +311,7 @@ def __new__(cls, data=None,
305311
raise TypeError("Already tz-aware, use tz_convert "
306312
"to convert.")
307313

308-
return data
314+
return data._deepcopy_if_needed(ref_to_data, copy)
309315

310316
if issubclass(data.dtype.type, compat.string_types):
311317
data = tslib.parse_str_array_to_datetime(data, freq=freq,
@@ -338,10 +344,7 @@ def __new__(cls, data=None,
338344
elif data.dtype == _INT64_DTYPE:
339345
if isinstance(data, Int64Index):
340346
raise TypeError('cannot convert Int64Index->DatetimeIndex')
341-
if copy:
342-
subarr = np.asarray(data, dtype=_NS_DTYPE)
343-
else:
344-
subarr = data.view(_NS_DTYPE)
347+
subarr = data.view(_NS_DTYPE)
345348
else:
346349
if isinstance(data, (ABCSeries, Index)):
347350
values = data._values
@@ -417,7 +420,7 @@ def __new__(cls, data=None,
417420
if inferred:
418421
subarr.offset = to_offset(inferred)
419422

420-
return subarr
423+
return subarr._deepcopy_if_needed(ref_to_data, copy)
421424

422425
@classmethod
423426
def _generate(cls, start, end, periods, name, offset,

0 commit comments

Comments
 (0)