-
-
Notifications
You must be signed in to change notification settings - Fork 19.4k
separate numeric tests so we can isolate division by zero #19336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
ba9240c
c19dff1
4182089
6f734bc
393a6c8
5e1d39f
9fb00cc
8fd7e31
4b78542
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -595,77 +595,85 @@ def test_divide_decimal(self): | |
|
|
||
| assert_series_equal(expected, s) | ||
|
|
||
| def test_div(self): | ||
| @pytest.mark.parametrize('dtype2', [np.int64, np.int32, np.int16, np.int8, | ||
| np.float64, np.float32, np.float16, | ||
| np.uint64, np.uint32, | ||
| np.uint16, np.uint8]) | ||
| @pytest.mark.parametrize('dtype1', [np.int64, np.float64, np.uint64]) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pls clean the parameterize up here as I suggested |
||
| def test_ser_div_ser(self, dtype1, dtype2): | ||
| # no longer do integer div for any ops, but deal with the 0's | ||
| first = Series([3, 4, 5, 8], name='first').astype(dtype1) | ||
| second = Series([0, 0, 0, 3], name='second').astype(dtype2) | ||
|
|
||
| with np.errstate(all='ignore'): | ||
| # no longer do integer div for any ops, but deal with the 0's | ||
| p = DataFrame({'first': [3, 4, 5, 8], 'second': [0, 0, 0, 3]}) | ||
| result = p['first'] / p['second'] | ||
| expected = Series( | ||
| p['first'].values.astype(float) / p['second'].values, | ||
| dtype='float64') | ||
| expected.iloc[0:3] = np.inf | ||
| assert_series_equal(result, expected) | ||
| expected = Series(first.values.astype(np.float64) / second.values, | ||
| dtype='float64') | ||
| expected.iloc[0:3] = np.inf | ||
|
|
||
| result = p['first'] / 0 | ||
| expected = Series(np.inf, index=p.index, name='first') | ||
| assert_series_equal(result, expected) | ||
| result = first / second | ||
| assert_series_equal(result, expected) | ||
|
|
||
| p = p.astype('float64') | ||
| result = p['first'] / p['second'] | ||
| expected = Series(p['first'].values / p['second'].values) | ||
| assert_series_equal(result, expected) | ||
| def test_ser_div_ser_name_propagation(self): | ||
|
||
| first = Series([3, 4, 5, 8], name='first') | ||
| second = Series([1, 1, 1, 1], name='second') | ||
|
|
||
| p = DataFrame({'first': [3, 4, 5, 8], 'second': [1, 1, 1, 1]}) | ||
| result = p['first'] / p['second'] | ||
| assert_series_equal(result, p['first'].astype('float64'), | ||
| check_names=False) | ||
| assert result.name is None | ||
| assert not result.equals(p['second'] / p['first']) | ||
|
|
||
| # inf signing | ||
| s = Series([np.nan, 1., -1.]) | ||
| result = s / 0 | ||
| expected = Series([np.nan, np.inf, -np.inf]) | ||
| assert_series_equal(result, expected) | ||
| expected = Series([3, 4, 5, 8], dtype='float64', name=None) | ||
| result = first / second | ||
| assert_series_equal(result, expected) | ||
| assert not result.equals(second / first) | ||
|
|
||
| # float/integer issue | ||
| # GH 7785 | ||
| p = DataFrame({'first': (1, 0), 'second': (-0.01, -0.02)}) | ||
| expected = Series([-0.01, -np.inf]) | ||
| def test_div_equiv_binop(self): | ||
| # Test Series.div as well as Series.__div__ | ||
| # float/integer issue | ||
| # GH#7785 | ||
| first = pd.Series([1, 0], name='first') | ||
| second = pd.Series([-0.01, -0.02], name='second') | ||
| expected = Series([-0.01, -np.inf]) | ||
|
|
||
| result = p['second'].div(p['first']) | ||
| assert_series_equal(result, expected, check_names=False) | ||
| result = second.div(first) | ||
| assert_series_equal(result, expected, check_names=False) | ||
|
|
||
| result = p['second'] / p['first'] | ||
| assert_series_equal(result, expected) | ||
| result = second / first | ||
| assert_series_equal(result, expected) | ||
|
|
||
| # GH 9144 | ||
| s = Series([-1, 0, 1]) | ||
| def test_rdiv_zero_compat(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. parametrie over 0 with various int/uint dtypes |
||
| # GH#8674 | ||
| zero_array = np.array([0] * 5) | ||
| data = np.random.randn(5) | ||
| expected = pd.Series([0.] * 5) | ||
|
|
||
| result = 0 / s | ||
| expected = Series([0.0, nan, 0.0]) | ||
| assert_series_equal(result, expected) | ||
| result = zero_array / pd.Series(data) | ||
| assert_series_equal(result, expected) | ||
|
|
||
| result = s / 0 | ||
| expected = Series([-inf, nan, inf]) | ||
| assert_series_equal(result, expected) | ||
| result = pd.Series(zero_array) / data | ||
| assert_series_equal(result, expected) | ||
|
|
||
| result = s // 0 | ||
| expected = Series([-inf, nan, inf]) | ||
| assert_series_equal(result, expected) | ||
| result = pd.Series(zero_array) / pd.Series(data) | ||
| assert_series_equal(result, expected) | ||
|
|
||
| # GH 8674 | ||
| zero_array = np.array([0] * 5) | ||
| data = np.random.randn(5) | ||
| expected = pd.Series([0.] * 5) | ||
| result = zero_array / pd.Series(data) | ||
| assert_series_equal(result, expected) | ||
| def test_div_zero_inf_signs(self): | ||
| # GH#9144, inf signing | ||
| ser = Series([-1, 0, 1], name='first') | ||
| expected = Series([-np.inf, np.nan, np.inf], name='first') | ||
|
|
||
| result = pd.Series(zero_array) / data | ||
| assert_series_equal(result, expected) | ||
| result = ser / 0 | ||
| assert_series_equal(result, expected) | ||
|
|
||
| result = pd.Series(zero_array) / pd.Series(data) | ||
| assert_series_equal(result, expected) | ||
| def test_rdiv_zero(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. parametrize |
||
| # GH#9144 | ||
| ser = Series([-1, 0, 1], name='first') | ||
| expected = Series([0.0, np.nan, 0.0], name='first') | ||
|
|
||
| result = 0 / ser | ||
| assert_series_equal(result, expected) | ||
|
|
||
| def test_floordiv_div(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same. see the pattern :> need to create a zero fixture |
||
| # GH#9144 | ||
| ser = Series([-1, 0, 1], name='first') | ||
|
|
||
| result = ser // 0 | ||
| expected = Series([-inf, nan, inf], name='first') | ||
| assert_series_equal(result, expected) | ||
|
|
||
|
|
||
| class TestTimedeltaSeriesArithmeticWithIntegers(object): | ||
|
|
@@ -1574,33 +1582,36 @@ def test_dt64_series_add_intlike(self, tz): | |
|
|
||
|
|
||
| class TestSeriesOperators(TestData): | ||
| def test_op_method(self): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add a comment to describe what tests this class does |
||
| def check(series, other, check_reverse=False): | ||
| simple_ops = ['add', 'sub', 'mul', 'floordiv', 'truediv', 'pow'] | ||
| if not compat.PY3: | ||
| simple_ops.append('div') | ||
|
|
||
| for opname in simple_ops: | ||
| op = getattr(Series, opname) | ||
|
|
||
| if op == 'div': | ||
| alt = operator.truediv | ||
| else: | ||
| alt = getattr(operator, opname) | ||
|
|
||
| result = op(series, other) | ||
| expected = alt(series, other) | ||
| assert_almost_equal(result, expected) | ||
| if check_reverse: | ||
| rop = getattr(Series, "r" + opname) | ||
| result = rop(series, other) | ||
| expected = alt(other, series) | ||
| assert_almost_equal(result, expected) | ||
| @pytest.mark.parametrize('ts', [lambda x: (x, x * 2, False), | ||
|
||
| lambda x: (x, x[::2], False), | ||
| lambda x: (x, 5, True), | ||
| lambda x: (tm.makeFloatSeries(), | ||
| tm.makeFloatSeries(), | ||
| True)]) | ||
| @pytest.mark.parametrize('opname', ['add', 'sub', 'mul', 'floordiv', | ||
| 'truediv', 'div', 'pow']) | ||
| def test_op_method(self, opname, ts): | ||
| # check that Series.{opname} behaves like Series.__{opname}__, | ||
| series, other, check_reverse = ts(self.ts) | ||
|
|
||
| if opname == 'div' and compat.PY3: | ||
| pytest.skip('div test only for Py3') | ||
|
|
||
| op = getattr(Series, opname) | ||
|
|
||
| if op == 'div': | ||
| alt = operator.truediv | ||
| else: | ||
| alt = getattr(operator, opname) | ||
|
|
||
| check(self.ts, self.ts * 2) | ||
| check(self.ts, self.ts[::2]) | ||
| check(self.ts, 5, check_reverse=True) | ||
| check(tm.makeFloatSeries(), tm.makeFloatSeries(), check_reverse=True) | ||
| result = op(series, other) | ||
| expected = alt(series, other) | ||
| assert_almost_equal(result, expected) | ||
| if check_reverse: | ||
| rop = getattr(Series, "r" + opname) | ||
| result = rop(series, other) | ||
| expected = alt(other, series) | ||
| assert_almost_equal(result, expected) | ||
|
|
||
| def test_neg(self): | ||
| assert_series_equal(-self.series, -1 * self.series) | ||
|
|
@@ -1992,20 +2003,15 @@ def test_operators_corner(self): | |
| index=self.ts.index[:-5], name='ts') | ||
| tm.assert_series_equal(added[:-5], expected) | ||
|
|
||
| def test_operators_reverse_object(self): | ||
| @pytest.mark.parametrize('op', [operator.add, operator.sub, operator.mul, | ||
| operator.truediv, operator.floordiv]) | ||
| def test_operators_reverse_object(self, op): | ||
| # GH 56 | ||
| arr = Series(np.random.randn(10), index=np.arange(10), dtype=object) | ||
|
|
||
| def _check_op(arr, op): | ||
| result = op(1., arr) | ||
| expected = op(1., arr.astype(float)) | ||
| assert_series_equal(result.astype(float), expected) | ||
|
|
||
| _check_op(arr, operator.add) | ||
| _check_op(arr, operator.sub) | ||
| _check_op(arr, operator.mul) | ||
| _check_op(arr, operator.truediv) | ||
| _check_op(arr, operator.floordiv) | ||
| result = op(1., arr) | ||
| expected = op(1., arr.astype(float)) | ||
| assert_series_equal(result.astype(float), expected) | ||
|
|
||
| def test_arith_ops_df_compat(self): | ||
| # GH 1134 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't this be better as a fixture
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe eventually. ATM it is only used once so there's no upside.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a style note, generally I would write this like
as it makes it shorter and more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd like this changed