@@ -447,6 +447,111 @@ def test_dti_with_offset_series(self, tz, names):
447447 tm .assert_series_equal (res3 , expected_sub )
448448
449449
450+ @pytest .mark .parametrize ('klass,assert_func' , [
451+ (Series , tm .assert_series_equal ),
452+ (DatetimeIndex , tm .assert_index_equal )])
453+ def test_dt64_with_offset_array (klass , assert_func ):
454+ # GH#10699
455+ # array of offsets
456+ box = Series if klass is Series else pd .Index
457+ with tm .assert_produces_warning (PerformanceWarning ):
458+ s = klass ([Timestamp ('2000-1-1' ), Timestamp ('2000-2-1' )])
459+ result = s + box ([pd .offsets .DateOffset (years = 1 ),
460+ pd .offsets .MonthEnd ()])
461+ exp = klass ([Timestamp ('2001-1-1' ), Timestamp ('2000-2-29' )])
462+ assert_func (result , exp )
463+
464+ # same offset
465+ result = s + box ([pd .offsets .DateOffset (years = 1 ),
466+ pd .offsets .DateOffset (years = 1 )])
467+ exp = klass ([Timestamp ('2001-1-1' ), Timestamp ('2001-2-1' )])
468+ assert_func (result , exp )
469+
470+
471+ @pytest .mark .parametrize ('klass,assert_func' , [
472+ (Series , tm .assert_series_equal ),
473+ (DatetimeIndex , tm .assert_index_equal )])
474+ def test_dt64_with_DateOffsets_relativedelta (klass , assert_func ):
475+ # GH#10699
476+ vec = klass ([Timestamp ('2000-01-05 00:15:00' ),
477+ Timestamp ('2000-01-31 00:23:00' ),
478+ Timestamp ('2000-01-01' ),
479+ Timestamp ('2000-03-31' ),
480+ Timestamp ('2000-02-29' ),
481+ Timestamp ('2000-12-31' ),
482+ Timestamp ('2000-05-15' ),
483+ Timestamp ('2001-06-15' )])
484+
485+ # DateOffset relativedelta fastpath
486+ relative_kwargs = [('years' , 2 ), ('months' , 5 ), ('days' , 3 ),
487+ ('hours' , 5 ), ('minutes' , 10 ), ('seconds' , 2 ),
488+ ('microseconds' , 5 )]
489+ for i , kwd in enumerate (relative_kwargs ):
490+ op = pd .DateOffset (** dict ([kwd ]))
491+ assert_func (klass ([x + op for x in vec ]), vec + op )
492+ assert_func (klass ([x - op for x in vec ]), vec - op )
493+ op = pd .DateOffset (** dict (relative_kwargs [:i + 1 ]))
494+ assert_func (klass ([x + op for x in vec ]), vec + op )
495+ assert_func (klass ([x - op for x in vec ]), vec - op )
496+
497+
498+ @pytest .mark .parametrize ('cls_name' , [
499+ 'YearBegin' , ('YearBegin' , {'month' : 5 }),
500+ 'YearEnd' , ('YearEnd' , {'month' : 5 }),
501+ 'MonthBegin' , 'MonthEnd' ,
502+ 'SemiMonthEnd' , 'SemiMonthBegin' ,
503+ 'Week' , ('Week' , {'weekday' : 3 }),
504+ 'BusinessDay' , 'BDay' , 'QuarterEnd' , 'QuarterBegin' ,
505+ 'CustomBusinessDay' , 'CDay' , 'CBMonthEnd' ,
506+ 'CBMonthBegin' , 'BMonthBegin' , 'BMonthEnd' ,
507+ 'BusinessHour' , 'BYearBegin' , 'BYearEnd' ,
508+ 'BQuarterBegin' , ('LastWeekOfMonth' , {'weekday' : 2 }),
509+ ('FY5253Quarter' , {'qtr_with_extra_week' : 1 ,
510+ 'startingMonth' : 1 ,
511+ 'weekday' : 2 ,
512+ 'variation' : 'nearest' }),
513+ ('FY5253' , {'weekday' : 0 , 'startingMonth' : 2 , 'variation' : 'nearest' }),
514+ ('WeekOfMonth' , {'weekday' : 2 , 'week' : 2 }),
515+ 'Easter' , ('DateOffset' , {'day' : 4 }),
516+ ('DateOffset' , {'month' : 5 })])
517+ @pytest .mark .parametrize ('normalize' , [True , False ])
518+ @pytest .mark .parametrize ('klass,assert_func' , [
519+ (Series , tm .assert_series_equal ),
520+ (DatetimeIndex , tm .assert_index_equal )])
521+ def test_dt64_with_DateOffsets (klass , assert_func , normalize , cls_name ):
522+ # GH#10699
523+ # assert these are equal on a piecewise basis
524+ vec = klass ([Timestamp ('2000-01-05 00:15:00' ),
525+ Timestamp ('2000-01-31 00:23:00' ),
526+ Timestamp ('2000-01-01' ),
527+ Timestamp ('2000-03-31' ),
528+ Timestamp ('2000-02-29' ),
529+ Timestamp ('2000-12-31' ),
530+ Timestamp ('2000-05-15' ),
531+ Timestamp ('2001-06-15' )])
532+
533+ if isinstance (cls_name , tuple ):
534+ # If cls_name param is a tuple, then 2nd entry is kwargs for
535+ # the offset constructor
536+ cls_name , kwargs = cls_name
537+ else :
538+ kwargs = {}
539+
540+ offset_cls = getattr (pd .offsets , cls_name )
541+
542+ with warnings .catch_warnings (record = True ):
543+ for n in [0 , 5 ]:
544+ if (cls_name in ['WeekOfMonth' , 'LastWeekOfMonth' ,
545+ 'FY5253Quarter' , 'FY5253' ] and n == 0 ):
546+ # passing n = 0 is invalid for these offset classes
547+ continue
548+
549+ offset = offset_cls (n , normalize = normalize , ** kwargs )
550+ assert_func (klass ([x + offset for x in vec ]), vec + offset )
551+ assert_func (klass ([x - offset for x in vec ]), vec - offset )
552+ assert_func (klass ([offset + x for x in vec ]), offset + vec )
553+
554+
450555# GH 10699
451556@pytest .mark .parametrize ('klass,assert_func' , zip ([Series , DatetimeIndex ],
452557 [tm .assert_series_equal ,
@@ -480,84 +585,3 @@ def test_datetime64_with_DateOffset(klass, assert_func):
480585 Timestamp ('2000-02-29' , tz = 'US/Central' )], name = 'a' )
481586 assert_func (result , exp )
482587 assert_func (result2 , exp )
483-
484- # array of offsets - valid for Series only
485- if klass is Series :
486- with tm .assert_produces_warning (PerformanceWarning ):
487- s = klass ([Timestamp ('2000-1-1' ), Timestamp ('2000-2-1' )])
488- result = s + Series ([pd .offsets .DateOffset (years = 1 ),
489- pd .offsets .MonthEnd ()])
490- exp = klass ([Timestamp ('2001-1-1' ), Timestamp ('2000-2-29' )
491- ])
492- assert_func (result , exp )
493-
494- # same offset
495- result = s + Series ([pd .offsets .DateOffset (years = 1 ),
496- pd .offsets .DateOffset (years = 1 )])
497- exp = klass ([Timestamp ('2001-1-1' ), Timestamp ('2001-2-1' )])
498- assert_func (result , exp )
499-
500- s = klass ([Timestamp ('2000-01-05 00:15:00' ),
501- Timestamp ('2000-01-31 00:23:00' ),
502- Timestamp ('2000-01-01' ),
503- Timestamp ('2000-03-31' ),
504- Timestamp ('2000-02-29' ),
505- Timestamp ('2000-12-31' ),
506- Timestamp ('2000-05-15' ),
507- Timestamp ('2001-06-15' )])
508-
509- # DateOffset relativedelta fastpath
510- relative_kwargs = [('years' , 2 ), ('months' , 5 ), ('days' , 3 ),
511- ('hours' , 5 ), ('minutes' , 10 ), ('seconds' , 2 ),
512- ('microseconds' , 5 )]
513- for i , kwd in enumerate (relative_kwargs ):
514- op = pd .DateOffset (** dict ([kwd ]))
515- assert_func (klass ([x + op for x in s ]), s + op )
516- assert_func (klass ([x - op for x in s ]), s - op )
517- op = pd .DateOffset (** dict (relative_kwargs [:i + 1 ]))
518- assert_func (klass ([x + op for x in s ]), s + op )
519- assert_func (klass ([x - op for x in s ]), s - op )
520-
521- # assert these are equal on a piecewise basis
522- offsets = ['YearBegin' , ('YearBegin' , {'month' : 5 }),
523- 'YearEnd' , ('YearEnd' , {'month' : 5 }),
524- 'MonthBegin' , 'MonthEnd' ,
525- 'SemiMonthEnd' , 'SemiMonthBegin' ,
526- 'Week' , ('Week' , {'weekday' : 3 }),
527- 'BusinessDay' , 'BDay' , 'QuarterEnd' , 'QuarterBegin' ,
528- 'CustomBusinessDay' , 'CDay' , 'CBMonthEnd' ,
529- 'CBMonthBegin' , 'BMonthBegin' , 'BMonthEnd' ,
530- 'BusinessHour' , 'BYearBegin' , 'BYearEnd' ,
531- 'BQuarterBegin' , ('LastWeekOfMonth' , {'weekday' : 2 }),
532- ('FY5253Quarter' , {'qtr_with_extra_week' : 1 ,
533- 'startingMonth' : 1 ,
534- 'weekday' : 2 ,
535- 'variation' : 'nearest' }),
536- ('FY5253' , {'weekday' : 0 ,
537- 'startingMonth' : 2 ,
538- 'variation' :
539- 'nearest' }),
540- ('WeekOfMonth' , {'weekday' : 2 ,
541- 'week' : 2 }),
542- 'Easter' , ('DateOffset' , {'day' : 4 }),
543- ('DateOffset' , {'month' : 5 })]
544-
545- with warnings .catch_warnings (record = True ):
546- for normalize in (True , False ):
547- for do in offsets :
548- if isinstance (do , tuple ):
549- do , kwargs = do
550- else :
551- do = do
552- kwargs = {}
553-
554- for n in [0 , 5 ]:
555- if (do in ['WeekOfMonth' , 'LastWeekOfMonth' ,
556- 'FY5253Quarter' , 'FY5253' ] and n == 0 ):
557- continue
558- op = getattr (pd .offsets , do )(n ,
559- normalize = normalize ,
560- ** kwargs )
561- assert_func (klass ([x + op for x in s ]), s + op )
562- assert_func (klass ([x - op for x in s ]), s - op )
563- assert_func (klass ([op + x for x in s ]), op + s )
0 commit comments