From ddc4479df14e9d516eb05d08cf29ace7588613b1 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Fri, 27 Apr 2018 16:58:37 +0200 Subject: [PATCH 1/7] ENH: linearly spaced date_range (GH 20808) --- doc/source/whatsnew/v0.23.0.txt | 1 + pandas/core/indexes/datetimes.py | 48 +++++++++++++++++-- .../indexes/datetimes/test_date_range.py | 15 ++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index ffa4f1068f84d..6fa7acc5c0a84 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -450,6 +450,7 @@ Other Enhancements - Updated ``to_gbq`` and ``read_gbq`` signature and documentation to reflect changes from the Pandas-GBQ library version 0.4.0. Adds intersphinx mapping to Pandas-GBQ library. (:issue:`20564`) +- :func:`pandas.core.indexes.datetimes.date_range` now returns a linearly spaced DatetimeIndex if ``start``, ``stop``, and ``periods`` are specified, but ``freq`` is not. (:issue:`20808`) .. _whatsnew_0230.api_breaking: diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index e0e7ba3e8b518..47408b0faec3a 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -2583,13 +2583,15 @@ def _generate_regular_range(start, end, periods, freq): return data -def date_range(start=None, end=None, periods=None, freq='D', tz=None, +def date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs): """ Return a fixed frequency DatetimeIndex. - Exactly two of the three parameters `start`, `end` and `periods` - must be specified. + Two or three of the three parameters `start`, `end` and `periods` + must be specified. If all three parameters are specified, and `freq` is + omitted, the resulting DatetimeIndex will have `periods` linearly spaced + elements between `start` and `end` (closed on both sides). Parameters ---------- @@ -2616,6 +2618,8 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None, the 'left', 'right', or both sides (None, the default). **kwargs For compatibility. Has no effect on the result. + Can be used to pass arguments to `pd.to_datetime` when specifying + `start`, `end`, and `periods`, but not `freq`. Returns ------- @@ -2631,7 +2635,7 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None, -------- **Specifying the values** - The next three examples generate the same `DatetimeIndex`, but vary + The next four examples generate the same `DatetimeIndex`, but vary the combination of `start`, `end` and `periods`. Specify `start` and `end`, with the default daily frequency. @@ -2655,6 +2659,13 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None, '2017-12-29', '2017-12-30', '2017-12-31', '2018-01-01'], dtype='datetime64[ns]', freq='D') + Specify `start`, `end`, and `periods`; the frequency is generated + automatically (linearly spaced). + + >>> pd.date_range(start='2018-04-24', end='2018-04-27', periods=3) + DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00', + '2018-04-27 00:00:00'], freq=None) + **Other Parameters** Changed the `freq` (frequency) to ``'M'`` (month end frequency). @@ -2704,7 +2715,36 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None, >>> pd.date_range(start='2017-01-01', end='2017-01-04', closed='right') DatetimeIndex(['2017-01-02', '2017-01-03', '2017-01-04'], dtype='datetime64[ns]', freq='D') + + Declare extra parameters (kwargs) to be used with the pd.to_datetime + function that is used when all three parameters `start`, `end`, and + `periods` are declared. + + >>> date_range('2018-04-24', '2018-04-27', periods=3, box=False) + array(['2018-04-24T00:00:00.000000000', '2018-04-25T12:00:00.000000000', + '2018-04-27T00:00:00.000000000'], dtype='datetime64[ns]') """ + + # See https://github.com/pandas-dev/pandas/issues/20808 + if freq is None and periods is not None and start is not None \ + and end is not None: + if is_float(periods): + periods = int(periods) + elif not is_integer(periods): + msg = 'periods must be a number, got {periods}' + raise TypeError(msg.format(periods=periods)) + + start = Timestamp(start) + end = Timestamp(end) + di = tools.to_datetime(np.linspace(start.value, end.value, periods), + **kwargs) + if name: + di.name = name + return di + + if freq is None: + freq = 'D' + return DatetimeIndex(start=start, end=end, periods=periods, freq=freq, tz=tz, normalize=normalize, name=name, closed=closed, **kwargs) diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index e5291ed52a86c..6fd38b4dd89f7 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -162,6 +162,21 @@ def test_date_range_ambiguous_arguments(self): with tm.assert_raises_regex(ValueError, msg): date_range(start, end, periods=10, freq='s') + def test_date_range_convenience_periods(self): + # GH 20808 + rng = date_range('2018-04-24', '2018-04-27', periods=3) + exp = pd.DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00', + '2018-04-27 00:00:00'], freq=None) + + tm.assert_index_equal(rng, exp) + + # Test if kwargs work for the to_datetime function used + rng = date_range('2018-04-24', '2018-04-27', periods=3, box=False) + exp = np.array(['2018-04-24T00:00:00', '2018-04-25T12:00:00', + '2018-04-27T00:00:00'], dtype='datetime64[ns]') + + assert (rng == exp).all() + def test_date_range_businesshour(self): idx = DatetimeIndex(['2014-07-04 09:00', '2014-07-04 10:00', '2014-07-04 11:00', From 73870a71eaeab7c852865cdb21992b3cc1a97b14 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Sat, 28 Apr 2018 00:13:32 +0200 Subject: [PATCH 2/7] ENH: linearly spaced date_range (GH 20808) --- pandas/core/indexes/datetimes.py | 27 ++++++++++++++----- .../indexes/datetimes/test_date_range.py | 22 ++++++++++++--- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 47408b0faec3a..be93786341134 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -2718,7 +2718,8 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, Declare extra parameters (kwargs) to be used with the pd.to_datetime function that is used when all three parameters `start`, `end`, and - `periods` are declared. + `periods` are declared. If this results in anything else than a + DatetimeIndex (like in this example), you cannot specify `tz` or `name`. >>> date_range('2018-04-24', '2018-04-27', periods=3, box=False) array(['2018-04-24T00:00:00.000000000', '2018-04-25T12:00:00.000000000', @@ -2726,20 +2727,32 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, """ # See https://github.com/pandas-dev/pandas/issues/20808 - if freq is None and periods is not None and start is not None \ - and end is not None: + if freq is None and com._all_not_none(periods, start, end): if is_float(periods): periods = int(periods) elif not is_integer(periods): msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) - start = Timestamp(start) - end = Timestamp(end) + start = Timestamp(start, tz=tz) + end = Timestamp(end, tz=tz) + + if normalize: + start = libts.normalize_date(start) + end = libts.normalize_date(end) + di = tools.to_datetime(np.linspace(start.value, end.value, periods), **kwargs) - if name: - di.name = name + + try: + if tz is not None: + di = di.tz_localize('UTC').tz_convert(tz) + if name is not None: + di.name = name + except AttributeError: + raise AttributeError("To specify the timezone or a name, the " + "result has to be a DatetimeIndex!") + return di if freq is None: diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index 6fd38b4dd89f7..d62935c9e1490 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -165,8 +165,8 @@ def test_date_range_ambiguous_arguments(self): def test_date_range_convenience_periods(self): # GH 20808 rng = date_range('2018-04-24', '2018-04-27', periods=3) - exp = pd.DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00', - '2018-04-27 00:00:00'], freq=None) + exp = DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00', + '2018-04-27 00:00:00'], freq=None) tm.assert_index_equal(rng, exp) @@ -175,7 +175,23 @@ def test_date_range_convenience_periods(self): exp = np.array(['2018-04-24T00:00:00', '2018-04-25T12:00:00', '2018-04-27T00:00:00'], dtype='datetime64[ns]') - assert (rng == exp).all() + tm.assert_numpy_array_equal(rng, exp) + + # Test if spacing remains linear if tz changes to dst in range + rng = date_range('2018-04-01 01:00:00', '2018-04-01 04:00:00', + tz='Australia/Sydney', periods=3) + exp = DatetimeIndex(['2018-04-01 01:00:00+11:00', + '2018-04-01 02:00:00+11:00', + '2018-04-01 02:00:00+10:00', + '2018-04-01 03:00:00+10:00', + '2018-04-01 04:00:00+10:00'], freq=None) + + # Test AttributeError is raised if result is not a DatetimeIndex + msg = ("To specify the timezone or a name, the " + "result has to be a DatetimeIndex!") + with tm.assert_raises_regex(AttributeError, msg): + rng = date_range('2018-04-24', '2018-04-27', periods=3.3, + name="abc", box=False) def test_date_range_businesshour(self): idx = DatetimeIndex(['2014-07-04 09:00', '2014-07-04 10:00', From 580bca2747b596e2d32e7863b0071be29ba52060 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Sat, 28 Apr 2018 00:16:04 +0200 Subject: [PATCH 3/7] ENH: linearly spaced date_range (GH 20808) --- doc/source/whatsnew/v0.23.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index dd3e02e096ac7..3e1253e4c49bb 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -450,7 +450,7 @@ Other Enhancements - Updated :meth:`DataFrame.to_gbq` and :meth:`pandas.read_gbq` signature and documentation to reflect changes from the Pandas-GBQ library version 0.4.0. Adds intersphinx mapping to Pandas-GBQ library. (:issue:`20564`) -- :func:`pandas.core.indexes.datetimes.date_range` now returns a linearly spaced DatetimeIndex if ``start``, ``stop``, and ``periods`` are specified, but ``freq`` is not. (:issue:`20808`) +- :func:`date_range` now returns a linearly spaced ``DatetimeIndex`` if ``start``, ``stop``, and ``periods`` are specified, but ``freq`` is not. (:issue:`20808`) .. _whatsnew_0230.api_breaking: From a46307a9ce3ffb1826f8e82c6317d11fe993ca9a Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Sat, 28 Apr 2018 00:19:18 +0200 Subject: [PATCH 4/7] ENH: linearly spaced date_range (GH 20808) --- pandas/tests/indexes/datetimes/test_date_range.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index d62935c9e1490..80338f21b485c 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -186,12 +186,12 @@ def test_date_range_convenience_periods(self): '2018-04-01 03:00:00+10:00', '2018-04-01 04:00:00+10:00'], freq=None) - # Test AttributeError is raised if result is not a DatetimeIndex + # Test AttributeError is raised if result is not a DatetimeIndex msg = ("To specify the timezone or a name, the " "result has to be a DatetimeIndex!") with tm.assert_raises_regex(AttributeError, msg): - rng = date_range('2018-04-24', '2018-04-27', periods=3.3, - name="abc", box=False) + rng = date_range('2018-04-24', '2018-04-27', periods=3.3, + name="abc", box=False) def test_date_range_businesshour(self): idx = DatetimeIndex(['2014-07-04 09:00', '2014-07-04 10:00', From 25959775a81bba767ac04f6378a6db363c1d0eb3 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Tue, 1 May 2018 19:53:24 +0200 Subject: [PATCH 5/7] Moved to DTI constructor, removed kwargs functionality --- pandas/core/indexes/datetimes.py | 95 ++++++------------- .../indexes/datetimes/test_date_range.py | 22 +---- 2 files changed, 34 insertions(+), 83 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index be93786341134..2fcd1ad667444 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -358,7 +358,7 @@ def __new__(cls, data=None, msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) - if data is None and freq is None: + if data is None and freq is None and com._any_none(periods, start, end): raise ValueError("Must provide freq argument if no data is " "supplied") @@ -474,9 +474,9 @@ def __new__(cls, data=None, @classmethod def _generate(cls, start, end, periods, name, freq, tz=None, normalize=False, ambiguous='raise', closed=None): - if com._count_not_none(start, end, periods) != 2: - raise ValueError('Of the three parameters: start, end, and ' - 'periods, exactly two must be specified') + if com._count_not_none(start, end, periods, freq) != 3: + raise ValueError('Of the four parameters: start, end, periods, and ' + 'freq, exactly three must be specified') _normalized = True @@ -574,23 +574,28 @@ def _generate(cls, start, end, periods, name, freq, if end.tz is None and start.tz is not None: start = start.replace(tzinfo=None) - if _use_cached_range(freq, _normalized, start, end): - index = cls._cached_range(start, end, periods=periods, - freq=freq, name=name) + if freq is not None: + if _use_cached_range(freq, _normalized, start, end): + index = cls._cached_range(start, end, periods=periods, + freq=freq, name=name) + else: + index = _generate_regular_range(start, end, periods, freq) + + if tz is not None and getattr(index, 'tz', None) is None: + index = conversion.tz_localize_to_utc(_ensure_int64(index), tz, + ambiguous=ambiguous) + index = index.view(_NS_DTYPE) + + # index is localized datetime64 array -> have to convert + # start/end as well to compare + if start is not None: + start = start.tz_localize(tz).asm8 + if end is not None: + end = end.tz_localize(tz).asm8 else: - index = _generate_regular_range(start, end, periods, freq) - - if tz is not None and getattr(index, 'tz', None) is None: - index = conversion.tz_localize_to_utc(_ensure_int64(index), tz, - ambiguous=ambiguous) - index = index.view(_NS_DTYPE) - - # index is localized datetime64 array -> have to convert - # start/end as well to compare - if start is not None: - start = start.tz_localize(tz).asm8 - if end is not None: - end = end.tz_localize(tz).asm8 + index = tools.to_datetime(np.linspace(start.value, end.value, periods)) + if tz is not None: + index = index.tz_localize('UTC').tz_convert(tz) if not left_closed and len(index) and index[0] == start: index = index[1:] @@ -2588,10 +2593,10 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, """ Return a fixed frequency DatetimeIndex. - Two or three of the three parameters `start`, `end` and `periods` - must be specified. If all three parameters are specified, and `freq` is - omitted, the resulting DatetimeIndex will have `periods` linearly spaced - elements between `start` and `end` (closed on both sides). + Of the three parameters `start`, `end`, `periods`, and `freq` exactly + three must be specified. If `freq` is omitted, the resulting DatetimeIndex + will have `periods` linearly spaced elements between `start` and `end` + (closed on both sides). Parameters ---------- @@ -2618,8 +2623,6 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, the 'left', 'right', or both sides (None, the default). **kwargs For compatibility. Has no effect on the result. - Can be used to pass arguments to `pd.to_datetime` when specifying - `start`, `end`, and `periods`, but not `freq`. Returns ------- @@ -2715,47 +2718,9 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, >>> pd.date_range(start='2017-01-01', end='2017-01-04', closed='right') DatetimeIndex(['2017-01-02', '2017-01-03', '2017-01-04'], dtype='datetime64[ns]', freq='D') - - Declare extra parameters (kwargs) to be used with the pd.to_datetime - function that is used when all three parameters `start`, `end`, and - `periods` are declared. If this results in anything else than a - DatetimeIndex (like in this example), you cannot specify `tz` or `name`. - - >>> date_range('2018-04-24', '2018-04-27', periods=3, box=False) - array(['2018-04-24T00:00:00.000000000', '2018-04-25T12:00:00.000000000', - '2018-04-27T00:00:00.000000000'], dtype='datetime64[ns]') """ - # See https://github.com/pandas-dev/pandas/issues/20808 - if freq is None and com._all_not_none(periods, start, end): - if is_float(periods): - periods = int(periods) - elif not is_integer(periods): - msg = 'periods must be a number, got {periods}' - raise TypeError(msg.format(periods=periods)) - - start = Timestamp(start, tz=tz) - end = Timestamp(end, tz=tz) - - if normalize: - start = libts.normalize_date(start) - end = libts.normalize_date(end) - - di = tools.to_datetime(np.linspace(start.value, end.value, periods), - **kwargs) - - try: - if tz is not None: - di = di.tz_localize('UTC').tz_convert(tz) - if name is not None: - di.name = name - except AttributeError: - raise AttributeError("To specify the timezone or a name, the " - "result has to be a DatetimeIndex!") - - return di - - if freq is None: + if freq is None and com._any_none(periods, start, end): freq = 'D' return DatetimeIndex(start=start, end=end, periods=periods, diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index 80338f21b485c..bbe9cb65eb1a9 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -157,8 +157,8 @@ def test_date_range_ambiguous_arguments(self): start = datetime(2011, 1, 1, 5, 3, 40) end = datetime(2011, 1, 1, 8, 9, 40) - msg = ('Of the three parameters: start, end, and periods, ' - 'exactly two must be specified') + msg = ('Of the four parameters: start, end, periods, and ' + 'freq, exactly three must be specified') with tm.assert_raises_regex(ValueError, msg): date_range(start, end, periods=10, freq='s') @@ -170,13 +170,6 @@ def test_date_range_convenience_periods(self): tm.assert_index_equal(rng, exp) - # Test if kwargs work for the to_datetime function used - rng = date_range('2018-04-24', '2018-04-27', periods=3, box=False) - exp = np.array(['2018-04-24T00:00:00', '2018-04-25T12:00:00', - '2018-04-27T00:00:00'], dtype='datetime64[ns]') - - tm.assert_numpy_array_equal(rng, exp) - # Test if spacing remains linear if tz changes to dst in range rng = date_range('2018-04-01 01:00:00', '2018-04-01 04:00:00', tz='Australia/Sydney', periods=3) @@ -186,13 +179,6 @@ def test_date_range_convenience_periods(self): '2018-04-01 03:00:00+10:00', '2018-04-01 04:00:00+10:00'], freq=None) - # Test AttributeError is raised if result is not a DatetimeIndex - msg = ("To specify the timezone or a name, the " - "result has to be a DatetimeIndex!") - with tm.assert_raises_regex(AttributeError, msg): - rng = date_range('2018-04-24', '2018-04-27', periods=3.3, - name="abc", box=False) - def test_date_range_businesshour(self): idx = DatetimeIndex(['2014-07-04 09:00', '2014-07-04 10:00', '2014-07-04 11:00', @@ -229,8 +215,8 @@ def test_date_range_businesshour(self): def test_range_misspecified(self): # GH #1095 - msg = ('Of the three parameters: start, end, and periods, ' - 'exactly two must be specified') + msg = ('Of the four parameters: start, end, periods, and ' + 'freq, exactly three must be specified') with tm.assert_raises_regex(ValueError, msg): date_range(start='1/1/2000') From 1015e656e1e6f52bcbd7d707897dc5cdff8bbd06 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Wed, 2 May 2018 21:44:32 +0200 Subject: [PATCH 6/7] Fixed Style Issues --- pandas/core/indexes/datetimes.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 092e0667bb319..5a0f6670f8a62 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -358,7 +358,8 @@ def __new__(cls, data=None, msg = 'periods must be a number, got {periods}' raise TypeError(msg.format(periods=periods)) - if data is None and freq is None and com._any_none(periods, start, end): + if data is None and freq is None \ + and com._any_none(periods, start, end): raise ValueError("Must provide freq argument if no data is " "supplied") @@ -467,8 +468,8 @@ def __new__(cls, data=None, def _generate(cls, start, end, periods, name, freq, tz=None, normalize=False, ambiguous='raise', closed=None): if com._count_not_none(start, end, periods, freq) != 3: - raise ValueError('Of the four parameters: start, end, periods, and ' - 'freq, exactly three must be specified') + raise ValueError('Of the four parameters: start, end, periods, ' + 'and freq, exactly three must be specified') _normalized = True @@ -569,13 +570,13 @@ def _generate(cls, start, end, periods, name, freq, if freq is not None: if _use_cached_range(freq, _normalized, start, end): index = cls._cached_range(start, end, periods=periods, - freq=freq, name=name) + freq=freq, name=name) else: index = _generate_regular_range(start, end, periods, freq) - + if tz is not None and getattr(index, 'tz', None) is None: - index = conversion.tz_localize_to_utc(_ensure_int64(index), tz, - ambiguous=ambiguous) + index = conversion.tz_localize_to_utc(_ensure_int64(index), + tz, ambiguous=ambiguous) index = index.view(_NS_DTYPE) # index is localized datetime64 array -> have to convert @@ -585,7 +586,8 @@ def _generate(cls, start, end, periods, name, freq, if end is not None: end = end.tz_localize(tz).asm8 else: - index = tools.to_datetime(np.linspace(start.value, end.value, periods)) + index = tools.to_datetime( + np.linspace(start.value, end.value, periods)) if tz is not None: index = index.tz_localize('UTC').tz_convert(tz) @@ -2575,9 +2577,9 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None, """ Return a fixed frequency DatetimeIndex. - Of the three parameters `start`, `end`, `periods`, and `freq` exactly - three must be specified. If `freq` is omitted, the resulting DatetimeIndex - will have `periods` linearly spaced elements between `start` and `end` + Of the three parameters `start`, `end`, `periods`, and `freq` exactly + three must be specified. If `freq` is omitted, the resulting DatetimeIndex + will have `periods` linearly spaced elements between `start` and `end` (closed on both sides). Parameters From 4d6cd23e627b3a1ebac4a7a308f18e0ab9d57c70 Mon Sep 17 00:00:00 2001 From: Onno Eberhard Date: Wed, 2 May 2018 21:47:57 +0200 Subject: [PATCH 7/7] Fixed Style Issues --- pandas/core/indexes/datetimes.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 5a0f6670f8a62..e9ab443a978f8 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -469,7 +469,7 @@ def _generate(cls, start, end, periods, name, freq, tz=None, normalize=False, ambiguous='raise', closed=None): if com._count_not_none(start, end, periods, freq) != 3: raise ValueError('Of the four parameters: start, end, periods, ' - 'and freq, exactly three must be specified') + 'and freq, exactly three must be specified') _normalized = True @@ -575,8 +575,9 @@ def _generate(cls, start, end, periods, name, freq, index = _generate_regular_range(start, end, periods, freq) if tz is not None and getattr(index, 'tz', None) is None: - index = conversion.tz_localize_to_utc(_ensure_int64(index), - tz, ambiguous=ambiguous) + index = conversion.tz_localize_to_utc(_ensure_int64(index), + tz, + ambiguous=ambiguous) index = index.view(_NS_DTYPE) # index is localized datetime64 array -> have to convert @@ -586,8 +587,8 @@ def _generate(cls, start, end, periods, name, freq, if end is not None: end = end.tz_localize(tz).asm8 else: - index = tools.to_datetime( - np.linspace(start.value, end.value, periods)) + index = tools.to_datetime(np.linspace(start.value, + end.value, periods)) if tz is not None: index = index.tz_localize('UTC').tz_convert(tz)