@@ -509,6 +509,56 @@ def test_equals_op(self):
509509 tm .assert_numpy_array_equal (index_a == item , expected3 )
510510 tm .assert_numpy_array_equal (series_a == item , expected3 )
511511
512+ def test_numpy_ufuncs (self ):
513+ # test ufuncs of numpy 1.9.2. see:
514+ # http://docs.scipy.org/doc/numpy/reference/ufuncs.html
515+
516+ # some functions are skipped because it may return different result
517+ # for unicode input depending on numpy version
518+
519+ for name , idx in compat .iteritems (self .indices ):
520+ for func in [np .exp , np .exp2 , np .expm1 , np .log , np .log2 , np .log10 ,
521+ np .log1p , np .sqrt , np .sin , np .cos ,
522+ np .tan , np .arcsin , np .arccos , np .arctan ,
523+ np .sinh , np .cosh , np .tanh , np .arcsinh , np .arccosh ,
524+ np .arctanh , np .deg2rad , np .rad2deg ]:
525+ if isinstance (idx , pd .tseries .base .DatetimeIndexOpsMixin ):
526+ # raise TypeError or ValueError (PeriodIndex)
527+ # PeriodIndex behavior should be changed in future version
528+ with tm .assertRaises (Exception ):
529+ func (idx )
530+ elif isinstance (idx , (Float64Index , Int64Index )):
531+ # coerces to float (e.g. np.sin)
532+ result = func (idx )
533+ exp = Index (func (idx .values ), name = idx .name )
534+ self .assert_index_equal (result , exp )
535+ self .assertIsInstance (result , pd .Float64Index )
536+ else :
537+ # raise AttributeError or TypeError
538+ if len (idx ) == 0 :
539+ continue
540+ else :
541+ with tm .assertRaises (Exception ):
542+ func (idx )
543+
544+ for func in [np .isfinite , np .isinf , np .isnan , np .signbit ]:
545+ if isinstance (idx , pd .tseries .base .DatetimeIndexOpsMixin ):
546+ # raise TypeError or ValueError (PeriodIndex)
547+ with tm .assertRaises (Exception ):
548+ func (idx )
549+ elif isinstance (idx , (Float64Index , Int64Index )):
550+ # results in bool array
551+ result = func (idx )
552+ exp = func (idx .values )
553+ self .assertIsInstance (result , np .ndarray )
554+ tm .assertNotIsInstance (result , Index )
555+ else :
556+ if len (idx ) == 0 :
557+ continue
558+ else :
559+ with tm .assertRaises (Exception ):
560+ func (idx )
561+
512562
513563class TestIndex (Base , tm .TestCase ):
514564 _holder = Index
@@ -2848,6 +2898,41 @@ def test_slice_keep_name(self):
28482898 idx = Int64Index ([1 , 2 ], name = 'asdf' )
28492899 self .assertEqual (idx .name , idx [1 :].name )
28502900
2901+ def test_ufunc_coercions (self ):
2902+ idx = pd .Int64Index ([1 , 2 , 3 , 4 , 5 ], name = 'x' )
2903+
2904+ result = np .sqrt (idx )
2905+ tm .assertIsInstance (result , Float64Index )
2906+ exp = pd .Float64Index (np .sqrt (np .array ([1 , 2 , 3 , 4 , 5 ])), name = 'x' )
2907+ tm .assert_index_equal (result , exp )
2908+
2909+ result = np .divide (idx , 2. )
2910+ tm .assertIsInstance (result , Float64Index )
2911+ exp = pd .Float64Index ([0.5 , 1. , 1.5 , 2. , 2.5 ], name = 'x' )
2912+ tm .assert_index_equal (result , exp )
2913+
2914+ # _evaluate_numeric_binop
2915+ result = idx + 2.
2916+ tm .assertIsInstance (result , Float64Index )
2917+ exp = pd .Float64Index ([3. , 4. , 5. , 6. , 7. ], name = 'x' )
2918+ tm .assert_index_equal (result , exp )
2919+
2920+ result = idx - 2.
2921+ tm .assertIsInstance (result , Float64Index )
2922+ exp = pd .Float64Index ([- 1. , 0. , 1. , 2. , 3. ], name = 'x' )
2923+ tm .assert_index_equal (result , exp )
2924+
2925+ result = idx * 1.
2926+ tm .assertIsInstance (result , Float64Index )
2927+ exp = pd .Float64Index ([1. , 2. , 3. , 4. , 5. ], name = 'x' )
2928+ tm .assert_index_equal (result , exp )
2929+
2930+ result = idx / 2.
2931+ tm .assertIsInstance (result , Float64Index )
2932+ exp = pd .Float64Index ([0.5 , 1. , 1.5 , 2. , 2.5 ], name = 'x' )
2933+ tm .assert_index_equal (result , exp )
2934+
2935+
28512936class DatetimeLike (Base ):
28522937
28532938 def test_str (self ):
@@ -3101,7 +3186,9 @@ def test_get_loc(self):
31013186 tolerance = timedelta (1 )), 1 )
31023187 with tm .assertRaisesRegexp (ValueError , 'must be convertible' ):
31033188 idx .get_loc ('2000-01-10' , method = 'nearest' , tolerance = 'foo' )
3104- with tm .assertRaisesRegexp (ValueError , 'different freq' ):
3189+
3190+ msg = 'Input has different freq from PeriodIndex\\ (freq=D\\ )'
3191+ with tm .assertRaisesRegexp (ValueError , msg ):
31053192 idx .get_loc ('2000-01-10' , method = 'nearest' , tolerance = '1 hour' )
31063193 with tm .assertRaises (KeyError ):
31073194 idx .get_loc ('2000-01-10' , method = 'nearest' , tolerance = '1 day' )
@@ -3119,7 +3206,8 @@ def test_get_indexer(self):
31193206 idx .get_indexer (target , 'nearest' , tolerance = '1 hour' ),
31203207 [0 , - 1 , 1 ])
31213208
3122- with self .assertRaisesRegexp (ValueError , 'different freq' ):
3209+ msg = 'Input has different freq from PeriodIndex\\ (freq=H\\ )'
3210+ with self .assertRaisesRegexp (ValueError , msg ):
31233211 idx .get_indexer (target , 'nearest' , tolerance = '1 minute' )
31243212
31253213 tm .assert_numpy_array_equal (
@@ -3215,6 +3303,44 @@ def test_numeric_compat(self):
32153303 def test_pickle_compat_construction (self ):
32163304 pass
32173305
3306+ def test_ufunc_coercions (self ):
3307+ # normal ops are also tested in tseries/test_timedeltas.py
3308+ idx = TimedeltaIndex (['2H' , '4H' , '6H' , '8H' , '10H' ],
3309+ freq = '2H' , name = 'x' )
3310+
3311+ for result in [idx * 2 , np .multiply (idx , 2 )]:
3312+ tm .assertIsInstance (result , TimedeltaIndex )
3313+ exp = TimedeltaIndex (['4H' , '8H' , '12H' , '16H' , '20H' ],
3314+ freq = '4H' , name = 'x' )
3315+ tm .assert_index_equal (result , exp )
3316+ self .assertEqual (result .freq , '4H' )
3317+
3318+ for result in [idx / 2 , np .divide (idx , 2 )]:
3319+ tm .assertIsInstance (result , TimedeltaIndex )
3320+ exp = TimedeltaIndex (['1H' , '2H' , '3H' , '4H' , '5H' ],
3321+ freq = 'H' , name = 'x' )
3322+ tm .assert_index_equal (result , exp )
3323+ self .assertEqual (result .freq , 'H' )
3324+
3325+ idx = TimedeltaIndex (['2H' , '4H' , '6H' , '8H' , '10H' ],
3326+ freq = '2H' , name = 'x' )
3327+ for result in [ - idx , np .negative (idx )]:
3328+ tm .assertIsInstance (result , TimedeltaIndex )
3329+ exp = TimedeltaIndex (['-2H' , '-4H' , '-6H' , '-8H' , '-10H' ],
3330+ freq = '-2H' , name = 'x' )
3331+ tm .assert_index_equal (result , exp )
3332+ self .assertEqual (result .freq , None )
3333+
3334+ idx = TimedeltaIndex (['-2H' , '-1H' , '0H' , '1H' , '2H' ],
3335+ freq = 'H' , name = 'x' )
3336+ for result in [ abs (idx ), np .absolute (idx )]:
3337+ tm .assertIsInstance (result , TimedeltaIndex )
3338+ exp = TimedeltaIndex (['2H' , '1H' , '0H' , '1H' , '2H' ],
3339+ freq = None , name = 'x' )
3340+ tm .assert_index_equal (result , exp )
3341+ self .assertEqual (result .freq , None )
3342+
3343+
32183344class TestMultiIndex (Base , tm .TestCase ):
32193345 _holder = MultiIndex
32203346 _multiprocess_can_split_ = True
0 commit comments