14
14
from pandas .core import ops
15
15
import pandas .util .testing as tm
16
16
17
+
18
+ def adjust_negative_zero (zero , expected ):
19
+ """
20
+ Helper to adjust the expected result if we are dividing by -0.0
21
+ as opposed to 0.0
22
+ """
23
+ if np .signbit (np .array (zero )).any ():
24
+ # All entries in the `zero` fixture should be either
25
+ # all-negative or no-negative.
26
+ assert np .signbit (np .array (zero )).all ()
27
+
28
+ expected *= - 1
29
+
30
+ return expected
31
+
32
+
17
33
# ------------------------------------------------------------------
18
34
# Comparisons
19
35
@@ -229,20 +245,27 @@ def test_div_zero(self, zero, numeric_idx):
229
245
idx = numeric_idx
230
246
231
247
expected = pd .Index ([np .nan , np .inf , np .inf , np .inf , np .inf ], dtype = np .float64 )
248
+ # We only adjust for Index, because Series does not yet apply
249
+ # the adjustment correctly.
250
+ expected2 = adjust_negative_zero (zero , expected )
251
+
232
252
result = idx / zero
233
- tm .assert_index_equal (result , expected )
253
+ tm .assert_index_equal (result , expected2 )
234
254
ser_compat = Series (idx ).astype ("i8" ) / np .array (zero ).astype ("i8" )
235
- tm .assert_series_equal (ser_compat , Series (result ))
255
+ tm .assert_series_equal (ser_compat , Series (expected ))
236
256
237
257
def test_floordiv_zero (self , zero , numeric_idx ):
238
258
idx = numeric_idx
239
259
240
260
expected = pd .Index ([np .nan , np .inf , np .inf , np .inf , np .inf ], dtype = np .float64 )
261
+ # We only adjust for Index, because Series does not yet apply
262
+ # the adjustment correctly.
263
+ expected2 = adjust_negative_zero (zero , expected )
241
264
242
265
result = idx // zero
243
- tm .assert_index_equal (result , expected )
266
+ tm .assert_index_equal (result , expected2 )
244
267
ser_compat = Series (idx ).astype ("i8" ) // np .array (zero ).astype ("i8" )
245
- tm .assert_series_equal (ser_compat , Series (result ))
268
+ tm .assert_series_equal (ser_compat , Series (expected ))
246
269
247
270
def test_mod_zero (self , zero , numeric_idx ):
248
271
idx = numeric_idx
@@ -258,11 +281,27 @@ def test_divmod_zero(self, zero, numeric_idx):
258
281
259
282
exleft = pd .Index ([np .nan , np .inf , np .inf , np .inf , np .inf ], dtype = np .float64 )
260
283
exright = pd .Index ([np .nan , np .nan , np .nan , np .nan , np .nan ], dtype = np .float64 )
284
+ exleft = adjust_negative_zero (zero , exleft )
261
285
262
286
result = divmod (idx , zero )
263
287
tm .assert_index_equal (result [0 ], exleft )
264
288
tm .assert_index_equal (result [1 ], exright )
265
289
290
+ @pytest .mark .parametrize ("op" , [operator .truediv , operator .floordiv ])
291
+ def test_div_negative_zero (self , zero , numeric_idx , op ):
292
+ # Check that -1 / -0.0 returns np.inf, not -np.inf
293
+ if isinstance (numeric_idx , pd .UInt64Index ):
294
+ return
295
+ idx = numeric_idx - 3
296
+
297
+ expected = pd .Index (
298
+ [- np .inf , - np .inf , - np .inf , np .nan , np .inf ], dtype = np .float64
299
+ )
300
+ expected = adjust_negative_zero (zero , expected )
301
+
302
+ result = op (idx , zero )
303
+ tm .assert_index_equal (result , expected )
304
+
266
305
# ------------------------------------------------------------------
267
306
268
307
@pytest .mark .parametrize ("dtype1" , [np .int64 , np .float64 , np .uint64 ])
@@ -896,6 +935,26 @@ def check(series, other):
896
935
check (tser , tser [::2 ])
897
936
check (tser , 5 )
898
937
938
+ @pytest .mark .xfail (
939
+ reason = "Series division does not yet fill 1/0 consistently; Index does."
940
+ )
941
+ def test_series_divmod_zero (self ):
942
+ # Check that divmod uses pandas convention for division by zero,
943
+ # which does not match numpy.
944
+ # pandas convention has
945
+ # 1/0 == np.inf
946
+ # -1/0 == -np.inf
947
+ # 1/-0.0 == -np.inf
948
+ # -1/-0.0 == np.inf
949
+ tser = tm .makeTimeSeries ().rename ("ts" )
950
+ other = tser * 0
951
+
952
+ result = divmod (tser , other )
953
+ exp1 = pd .Series ([np .inf ] * len (tser ), index = tser .index )
954
+ exp2 = pd .Series ([np .nan ] * len (tser ), index = tser .index )
955
+ tm .assert_series_equal (result [0 ], exp1 )
956
+ tm .assert_series_equal (result [1 ], exp2 )
957
+
899
958
900
959
class TestUFuncCompat :
901
960
@pytest .mark .parametrize (
0 commit comments