@@ -358,7 +358,8 @@ def __new__(cls, data=None,
358
358
msg = 'periods must be a number, got {periods}'
359
359
raise TypeError (msg .format (periods = periods ))
360
360
361
- if data is None and freq is None :
361
+ if data is None and freq is None \
362
+ and com ._any_none (periods , start , end ):
362
363
raise ValueError ("Must provide freq argument if no data is "
363
364
"supplied" )
364
365
@@ -466,9 +467,9 @@ def __new__(cls, data=None,
466
467
@classmethod
467
468
def _generate (cls , start , end , periods , name , freq ,
468
469
tz = None , normalize = False , ambiguous = 'raise' , closed = None ):
469
- if com ._count_not_none (start , end , periods ) != 2 :
470
- raise ValueError ('Of the three parameters: start, end, and '
471
- 'periods , exactly two must be specified' )
470
+ if com ._count_not_none (start , end , periods , freq ) != 3 :
471
+ raise ValueError ('Of the four parameters: start, end, periods, '
472
+ 'and freq , exactly three must be specified' )
472
473
473
474
_normalized = True
474
475
@@ -566,23 +567,30 @@ def _generate(cls, start, end, periods, name, freq,
566
567
if end .tz is None and start .tz is not None :
567
568
start = start .replace (tzinfo = None )
568
569
569
- if _use_cached_range (freq , _normalized , start , end ):
570
- index = cls ._cached_range (start , end , periods = periods ,
571
- freq = freq , name = name )
570
+ if freq is not None :
571
+ if _use_cached_range (freq , _normalized , start , end ):
572
+ index = cls ._cached_range (start , end , periods = periods ,
573
+ freq = freq , name = name )
574
+ else :
575
+ index = _generate_regular_range (start , end , periods , freq )
576
+
577
+ if tz is not None and getattr (index , 'tz' , None ) is None :
578
+ index = conversion .tz_localize_to_utc (_ensure_int64 (index ),
579
+ tz ,
580
+ ambiguous = ambiguous )
581
+ index = index .view (_NS_DTYPE )
582
+
583
+ # index is localized datetime64 array -> have to convert
584
+ # start/end as well to compare
585
+ if start is not None :
586
+ start = start .tz_localize (tz ).asm8
587
+ if end is not None :
588
+ end = end .tz_localize (tz ).asm8
572
589
else :
573
- index = _generate_regular_range (start , end , periods , freq )
574
-
575
- if tz is not None and getattr (index , 'tz' , None ) is None :
576
- index = conversion .tz_localize_to_utc (_ensure_int64 (index ), tz ,
577
- ambiguous = ambiguous )
578
- index = index .view (_NS_DTYPE )
579
-
580
- # index is localized datetime64 array -> have to convert
581
- # start/end as well to compare
582
- if start is not None :
583
- start = start .tz_localize (tz ).asm8
584
- if end is not None :
585
- end = end .tz_localize (tz ).asm8
590
+ index = tools .to_datetime (np .linspace (start .value ,
591
+ end .value , periods ))
592
+ if tz is not None :
593
+ index = index .tz_localize ('UTC' ).tz_convert (tz )
586
594
587
595
if not left_closed and len (index ) and index [0 ] == start :
588
596
index = index [1 :]
@@ -2565,13 +2573,15 @@ def _generate_regular_range(start, end, periods, freq):
2565
2573
return data
2566
2574
2567
2575
2568
- def date_range (start = None , end = None , periods = None , freq = 'D' , tz = None ,
2576
+ def date_range (start = None , end = None , periods = None , freq = None , tz = None ,
2569
2577
normalize = False , name = None , closed = None , ** kwargs ):
2570
2578
"""
2571
2579
Return a fixed frequency DatetimeIndex.
2572
2580
2573
- Exactly two of the three parameters `start`, `end` and `periods`
2574
- must be specified.
2581
+ Of the three parameters `start`, `end`, `periods`, and `freq` exactly
2582
+ three must be specified. If `freq` is omitted, the resulting DatetimeIndex
2583
+ will have `periods` linearly spaced elements between `start` and `end`
2584
+ (closed on both sides).
2575
2585
2576
2586
Parameters
2577
2587
----------
@@ -2613,7 +2623,7 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
2613
2623
--------
2614
2624
**Specifying the values**
2615
2625
2616
- The next three examples generate the same `DatetimeIndex`, but vary
2626
+ The next four examples generate the same `DatetimeIndex`, but vary
2617
2627
the combination of `start`, `end` and `periods`.
2618
2628
2619
2629
Specify `start` and `end`, with the default daily frequency.
@@ -2637,6 +2647,13 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
2637
2647
'2017-12-29', '2017-12-30', '2017-12-31', '2018-01-01'],
2638
2648
dtype='datetime64[ns]', freq='D')
2639
2649
2650
+ Specify `start`, `end`, and `periods`; the frequency is generated
2651
+ automatically (linearly spaced).
2652
+
2653
+ >>> pd.date_range(start='2018-04-24', end='2018-04-27', periods=3)
2654
+ DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00',
2655
+ '2018-04-27 00:00:00'], freq=None)
2656
+
2640
2657
**Other Parameters**
2641
2658
2642
2659
Changed the `freq` (frequency) to ``'M'`` (month end frequency).
@@ -2687,6 +2704,10 @@ def date_range(start=None, end=None, periods=None, freq='D', tz=None,
2687
2704
DatetimeIndex(['2017-01-02', '2017-01-03', '2017-01-04'],
2688
2705
dtype='datetime64[ns]', freq='D')
2689
2706
"""
2707
+
2708
+ if freq is None and com ._any_none (periods , start , end ):
2709
+ freq = 'D'
2710
+
2690
2711
return DatetimeIndex (start = start , end = end , periods = periods ,
2691
2712
freq = freq , tz = tz , normalize = normalize , name = name ,
2692
2713
closed = closed , ** kwargs )
0 commit comments