diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 58c07a14dec39..883dd176f0a59 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -312,7 +312,7 @@ Reshaping - Bug in :func:`merge` when merging by index name would sometimes result in an incorrectly numbered index (:issue:`24212`) - :func:`to_records` now accepts dtypes to its `column_dtypes` parameter (:issue:`24895`) - Bug in :func:`concat` where order of ``OrderedDict`` (and ``dict`` in Python 3.6+) is not respected, when passed in as ``objs`` argument (:issue:`21510`) - +- Bug in :func:`concat` where the resulting ``freq`` of two :class:`DatetimeIndex` with the same ``freq`` would be dropped (:issue:`3232`). Sparse ^^^^^^ diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 830f234b85757..da4e7040097a2 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -8,6 +8,7 @@ import numpy as np from pandas._libs import NaT, iNaT, lib +from pandas._libs.algos import unique_deltas from pandas.compat.numpy import function as nv from pandas.errors import AbstractMethodError from pandas.util._decorators import Appender, cache_readonly, deprecate_kwarg @@ -587,11 +588,15 @@ def _concat_same_dtype(self, to_concat, name): if len({str(x.dtype) for x in to_concat}) != 1: raise ValueError('to_concat must have the same tz') - if not is_period_dtype(self): + new_data = type(self._values)._concat_same_type(to_concat).asi8 + + # GH 3232: If the concat result is evenly spaced, we can retain the + # original frequency + is_diff_evenly_spaced = len(unique_deltas(new_data)) == 1 + if not is_period_dtype(self) and not is_diff_evenly_spaced: # reset freq attribs['freq'] = None - new_data = type(self._values)._concat_same_type(to_concat).asi8 return self._simple_new(new_data, **attribs) @Appender(_index_shared_docs['astype']) diff --git a/pandas/tests/reshape/test_concat.py b/pandas/tests/reshape/test_concat.py index 08d80a24c092f..bf77ad0b1e7c8 100644 --- a/pandas/tests/reshape/test_concat.py +++ b/pandas/tests/reshape/test_concat.py @@ -2532,3 +2532,20 @@ def test_concat_categorical_tz(): 'a', 'b' ]) tm.assert_series_equal(result, expected) + + +def test_concat_datetimeindex_freq(): + # GH 3232 + # Monotonic index result + dr = pd.date_range('01-Jan-2013', periods=100, freq='50L', tz='UTC') + data = list(range(100)) + expected = pd.DataFrame(data, index=dr) + result = pd.concat([expected[:50], expected[50:]]) + tm.assert_frame_equal(result, expected) + + # Non-monotonic index result + result = pd.concat([expected[50:], expected[:50]]) + expected = pd.DataFrame(data[50:] + data[:50], + index=dr[50:].append(dr[:50])) + expected.index.freq = None + tm.assert_frame_equal(result, expected)