22
22
)
23
23
import pandas ._testing as tm
24
24
from pandas .core import ops
25
- from pandas .core .api import (
26
- Float64Index ,
27
- Int64Index ,
28
- UInt64Index ,
29
- )
25
+ from pandas .core .api import NumericIndex
30
26
from pandas .core .computation import expressions as expr
31
27
from pandas .tests .arithmetic .common import (
32
28
assert_invalid_addsub_type ,
@@ -375,7 +371,7 @@ def test_divmod_zero(self, zero, numeric_idx):
375
371
@pytest .mark .parametrize ("op" , [operator .truediv , operator .floordiv ])
376
372
def test_div_negative_zero (self , zero , numeric_idx , op ):
377
373
# Check that -1 / -0.0 returns np.inf, not -np.inf
378
- if isinstance (numeric_idx , UInt64Index ):
374
+ if tm . is_unsigned_integer_dtype (numeric_idx ):
379
375
return
380
376
idx = numeric_idx - 3
381
377
@@ -667,15 +663,15 @@ def test_mul_int_array(self, numeric_idx):
667
663
result = idx * np .array (5 , dtype = "int64" )
668
664
tm .assert_index_equal (result , idx * 5 )
669
665
670
- arr_dtype = "uint64" if isinstance (idx , UInt64Index ) else "int64"
666
+ arr_dtype = "uint64" if tm . is_unsigned_integer_dtype (idx ) else "int64"
671
667
result = idx * np .arange (5 , dtype = arr_dtype )
672
668
tm .assert_index_equal (result , didx )
673
669
674
670
def test_mul_int_series (self , numeric_idx ):
675
671
idx = numeric_idx
676
672
didx = idx * idx
677
673
678
- arr_dtype = "uint64" if isinstance (idx , UInt64Index ) else "int64"
674
+ arr_dtype = "uint64" if tm . is_unsigned_integer_dtype (idx ) else "int64"
679
675
result = idx * Series (np .arange (5 , dtype = arr_dtype ))
680
676
tm .assert_series_equal (result , Series (didx ))
681
677
@@ -712,7 +708,7 @@ def test_pow_float(self, op, numeric_idx, box_with_array):
712
708
# test power calculations both ways, GH#14973
713
709
box = box_with_array
714
710
idx = numeric_idx
715
- expected = Float64Index (op (idx .values , 2.0 ))
711
+ expected = NumericIndex (op (idx .values , 2.0 ), dtype = np . float64 )
716
712
717
713
idx = tm .box_expected (idx , box )
718
714
expected = tm .box_expected (expected , box )
@@ -1056,74 +1052,92 @@ def test_series_divmod_zero(self):
1056
1052
1057
1053
1058
1054
class TestUFuncCompat :
1059
- @pytest .mark .parametrize (
1060
- "holder" ,
1061
- [Int64Index , UInt64Index , Float64Index , RangeIndex , Series ],
1062
- )
1063
- def test_ufunc_compat (self , holder ):
1064
- box = Series if holder is Series else Index
1055
+ @pytest .mark .parametrize ("holder" , [NumericIndex , RangeIndex , Series ])
1056
+ def test_ufunc_compat (self , holder , any_real_numpy_dtype ):
1057
+ dtype = any_real_numpy_dtype
1065
1058
1059
+ if holder is RangeIndex and dtype != "int64" :
1060
+ pytest .skip ("Not relevant for RangeIndex" )
1061
+
1062
+ box = Series if holder is Series else NumericIndex
1066
1063
if holder is RangeIndex :
1067
1064
idx = RangeIndex (0 , 5 , name = "foo" )
1068
1065
else :
1069
- idx = holder (np .arange (5 , dtype = "int64" ), name = "foo" )
1066
+ idx = holder (np .arange (5 , dtype = "int64" ), dtype = dtype , name = "foo" )
1067
+
1070
1068
result = np .sin (idx )
1071
- expected = box (np .sin (np .arange (5 , dtype = "int64" )), name = "foo" )
1069
+
1070
+ if dtype in ["int8" , "uint8" ]:
1071
+ # index doesn't support float16
1072
+ expected_dtype = np .float32 if holder is NumericIndex else np .float16
1073
+ elif dtype in ["int16" , "uint16" , "float32" ]:
1074
+ expected_dtype = np .float32
1075
+ else :
1076
+ expected_dtype = np .float64
1077
+ exp_val = np .sin (np .arange (5 , dtype = dtype )).astype (expected_dtype )
1078
+ expected = box (exp_val , name = "foo" )
1072
1079
tm .assert_equal (result , expected )
1073
1080
1074
- @pytest .mark .parametrize ("holder" , [Int64Index , UInt64Index , Float64Index , Series ])
1075
- def test_ufunc_coercions (self , holder ):
1076
- idx = holder ([1 , 2 , 3 , 4 , 5 ], name = "x" )
1077
- box = Series if holder is Series else Index
1081
+ @pytest .mark .parametrize ("holder" , [NumericIndex , Series ])
1082
+ def test_ufunc_coercions (self , holder , any_real_numpy_dtype ):
1083
+ dtype = any_real_numpy_dtype
1084
+ idx = holder ([1 , 2 , 3 , 4 , 5 ], dtype = dtype , name = "x" )
1085
+ box = Series if holder is Series else NumericIndex
1086
+
1087
+ if dtype in ["int8" , "uint8" ]:
1088
+ # index doesn't support float16
1089
+ expected_dtype = np .float32 if holder is NumericIndex else np .float16
1090
+ elif dtype in ["int16" , "uint16" , "float32" ]:
1091
+ expected_dtype = np .float32
1092
+ else :
1093
+ expected_dtype = np .float64
1078
1094
1079
1095
result = np .sqrt (idx )
1080
- assert result .dtype == "f8" and isinstance (result , box )
1081
- exp = Float64Index ( np .sqrt (np .array ([1 , 2 , 3 , 4 , 5 ])), name = "x" )
1082
- exp = tm . box_expected ( exp , box )
1096
+ assert result .dtype == expected_dtype and isinstance (result , box )
1097
+ exp_val = np .sqrt (np .array ([1 , 2 , 3 , 4 , 5 ], dtype = dtype )). astype ( expected_dtype )
1098
+ exp = box ( exp_val , name = "x" )
1083
1099
tm .assert_equal (result , exp )
1084
1100
1101
+ expected_dtype = dtype if tm .is_float_dtype (dtype ) else np .float64
1102
+
1085
1103
result = np .divide (idx , 2.0 )
1086
- assert result .dtype == "f8" and isinstance (result , box )
1087
- exp = Float64Index ([0.5 , 1.0 , 1.5 , 2.0 , 2.5 ], name = "x" )
1088
- exp = tm .box_expected (exp , box )
1104
+ assert result .dtype == expected_dtype and isinstance (result , box )
1105
+ exp = box ([0.5 , 1.0 , 1.5 , 2.0 , 2.5 ], dtype = expected_dtype , name = "x" )
1089
1106
tm .assert_equal (result , exp )
1090
1107
1091
1108
# _evaluate_numeric_binop
1092
1109
result = idx + 2.0
1093
- assert result .dtype == "f8" and isinstance (result , box )
1094
- exp = Float64Index ([3.0 , 4.0 , 5.0 , 6.0 , 7.0 ], name = "x" )
1095
- exp = tm .box_expected (exp , box )
1110
+ assert result .dtype == expected_dtype and isinstance (result , box )
1111
+ exp = box ([3.0 , 4.0 , 5.0 , 6.0 , 7.0 ], dtype = expected_dtype , name = "x" )
1096
1112
tm .assert_equal (result , exp )
1097
1113
1098
1114
result = idx - 2.0
1099
- assert result .dtype == "f8" and isinstance (result , box )
1100
- exp = Float64Index ([- 1.0 , 0.0 , 1.0 , 2.0 , 3.0 ], name = "x" )
1101
- exp = tm .box_expected (exp , box )
1115
+ assert result .dtype == expected_dtype and isinstance (result , box )
1116
+ exp = box ([- 1.0 , 0.0 , 1.0 , 2.0 , 3.0 ], dtype = expected_dtype , name = "x" )
1102
1117
tm .assert_equal (result , exp )
1103
1118
1104
1119
result = idx * 1.0
1105
- assert result .dtype == "f8" and isinstance (result , box )
1106
- exp = Float64Index ([1.0 , 2.0 , 3.0 , 4.0 , 5.0 ], name = "x" )
1107
- exp = tm .box_expected (exp , box )
1120
+ assert result .dtype == expected_dtype and isinstance (result , box )
1121
+ exp = box ([1.0 , 2.0 , 3.0 , 4.0 , 5.0 ], dtype = expected_dtype , name = "x" )
1108
1122
tm .assert_equal (result , exp )
1109
1123
1110
1124
result = idx / 2.0
1111
- assert result .dtype == "f8" and isinstance (result , box )
1112
- exp = Float64Index ([0.5 , 1.0 , 1.5 , 2.0 , 2.5 ], name = "x" )
1113
- exp = tm .box_expected (exp , box )
1125
+ assert result .dtype == expected_dtype and isinstance (result , box )
1126
+ exp = box ([0.5 , 1.0 , 1.5 , 2.0 , 2.5 ], dtype = expected_dtype , name = "x" )
1114
1127
tm .assert_equal (result , exp )
1115
1128
1116
- @pytest .mark .parametrize ("holder" , [Int64Index , UInt64Index , Float64Index , Series ])
1117
- def test_ufunc_multiple_return_values (self , holder ):
1118
- obj = holder ([1 , 2 , 3 ], name = "x" )
1119
- box = Series if holder is Series else Index
1129
+ @pytest .mark .parametrize ("holder" , [NumericIndex , Series ])
1130
+ @pytest .mark .parametrize ("dtype" , ["int64" , "uint64" , "float64" ])
1131
+ def test_ufunc_multiple_return_values (self , holder , dtype ):
1132
+ obj = holder ([1 , 2 , 3 ], dtype = dtype , name = "x" )
1133
+ box = Series if holder is Series else NumericIndex
1120
1134
1121
1135
result = np .modf (obj )
1122
1136
assert isinstance (result , tuple )
1123
- exp1 = Float64Index ([0.0 , 0.0 , 0.0 ], name = "x" )
1124
- exp2 = Float64Index ([1.0 , 2.0 , 3.0 ], name = "x" )
1125
- tm .assert_equal (result [0 ], tm . box_expected ( exp1 , box ) )
1126
- tm .assert_equal (result [1 ], tm . box_expected ( exp2 , box ) )
1137
+ exp1 = box ([0.0 , 0.0 , 0.0 ], dtype = np . float64 , name = "x" )
1138
+ exp2 = box ([1.0 , 2.0 , 3.0 ], dtype = np . float64 , name = "x" )
1139
+ tm .assert_equal (result [0 ], exp1 )
1140
+ tm .assert_equal (result [1 ], exp2 )
1127
1141
1128
1142
def test_ufunc_at (self ):
1129
1143
s = Series ([0 , 1 , 2 ], index = [1 , 2 , 3 ], name = "x" )
@@ -1214,7 +1228,7 @@ def test_binops_index(self, op, idx1, idx2):
1214
1228
idx1 = idx1 ._rename ("foo" )
1215
1229
idx2 = idx2 ._rename ("bar" )
1216
1230
result = op (idx1 , idx2 )
1217
- expected = op (Int64Index (idx1 ), Int64Index (idx2 ))
1231
+ expected = op (NumericIndex (idx1 . to_numpy ()), NumericIndex (idx2 . to_numpy () ))
1218
1232
tm .assert_index_equal (result , expected , exact = "equiv" )
1219
1233
1220
1234
@pytest .mark .parametrize (
@@ -1239,7 +1253,7 @@ def test_binops_index(self, op, idx1, idx2):
1239
1253
@pytest .mark .parametrize ("scalar" , [- 1 , 1 , 2 ])
1240
1254
def test_binops_index_scalar (self , op , idx , scalar ):
1241
1255
result = op (idx , scalar )
1242
- expected = op (Int64Index (idx ), scalar )
1256
+ expected = op (NumericIndex (idx . to_numpy (), dtype = np . int64 ), scalar )
1243
1257
tm .assert_index_equal (result , expected , exact = "equiv" )
1244
1258
1245
1259
@pytest .mark .parametrize ("idx1" , [RangeIndex (0 , 10 , 1 ), RangeIndex (0 , 20 , 2 )])
@@ -1250,7 +1264,10 @@ def test_binops_index_pow(self, idx1, idx2):
1250
1264
idx1 = idx1 ._rename ("foo" )
1251
1265
idx2 = idx2 ._rename ("bar" )
1252
1266
result = pow (idx1 , idx2 )
1253
- expected = pow (Int64Index (idx1 ), Int64Index (idx2 ))
1267
+ expected = pow (
1268
+ NumericIndex (idx1 .to_numpy (), dtype = np .int64 ),
1269
+ NumericIndex (idx2 .to_numpy (), dtype = np .int64 ),
1270
+ )
1254
1271
tm .assert_index_equal (result , expected , exact = "equiv" )
1255
1272
1256
1273
@pytest .mark .parametrize ("idx" , [RangeIndex (0 , 10 , 1 ), RangeIndex (0 , 20 , 2 )])
@@ -1259,7 +1276,7 @@ def test_binops_index_scalar_pow(self, idx, scalar):
1259
1276
# numpy does not allow powers of negative integers so test separately
1260
1277
# https://github.com/numpy/numpy/pull/8127
1261
1278
result = pow (idx , scalar )
1262
- expected = pow (Int64Index (idx ), scalar )
1279
+ expected = pow (NumericIndex (idx . to_numpy (), dtype = np . int64 ), scalar )
1263
1280
tm .assert_index_equal (result , expected , exact = "equiv" )
1264
1281
1265
1282
# TODO: divmod?
@@ -1328,7 +1345,7 @@ def test_numeric_compat2(self):
1328
1345
# __pow__
1329
1346
idx = RangeIndex (0 , 1000 , 2 )
1330
1347
result = idx ** 2
1331
- expected = Int64Index (idx ._values ) ** 2
1348
+ expected = NumericIndex (idx ._values , dtype = np . int64 ) ** 2
1332
1349
tm .assert_index_equal (Index (result .values ), expected , exact = True )
1333
1350
1334
1351
@pytest .mark .parametrize (
@@ -1339,12 +1356,12 @@ def test_numeric_compat2(self):
1339
1356
(
1340
1357
RangeIndex (0 , 1000 , 1 ),
1341
1358
2 ,
1342
- Int64Index (RangeIndex (0 , 1000 , 1 )._values ) // 2 ,
1359
+ NumericIndex (RangeIndex (0 , 1000 , 1 )._values ) // 2 ,
1343
1360
),
1344
1361
(
1345
1362
RangeIndex (0 , 100 , 1 ),
1346
1363
2.0 ,
1347
- Int64Index (RangeIndex (0 , 100 , 1 )._values ) // 2.0 ,
1364
+ NumericIndex (RangeIndex (0 , 100 , 1 )._values ) // 2.0 ,
1348
1365
),
1349
1366
(RangeIndex (0 ), 50 , RangeIndex (0 )),
1350
1367
(RangeIndex (2 , 4 , 2 ), 3 , RangeIndex (0 , 1 , 1 )),
0 commit comments