From 54c91de86e582b9acdcd39756da0ef39e952c943 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 1 Apr 2020 11:20:18 -0700 Subject: [PATCH 1/3] REF: .dot tests --- pandas/tests/frame/test_analytics.py | 53 ---------- pandas/tests/generic/methods/test_dot.py | 128 +++++++++++++++++++++++ pandas/tests/series/test_analytics.py | 32 ------ 3 files changed, 128 insertions(+), 85 deletions(-) create mode 100644 pandas/tests/generic/methods/test_dot.py diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 6525e93d89fce..a23bc090687ac 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -1147,59 +1147,6 @@ def test_any_all_level_axis_none_raises(self, method): # --------------------------------------------------------------------- # Matrix-like - def test_dot(self): - a = DataFrame( - np.random.randn(3, 4), index=["a", "b", "c"], columns=["p", "q", "r", "s"] - ) - b = DataFrame( - np.random.randn(4, 2), index=["p", "q", "r", "s"], columns=["one", "two"] - ) - - result = a.dot(b) - expected = DataFrame( - np.dot(a.values, b.values), index=["a", "b", "c"], columns=["one", "two"] - ) - # Check alignment - b1 = b.reindex(index=reversed(b.index)) - result = a.dot(b) - tm.assert_frame_equal(result, expected) - - # Check series argument - result = a.dot(b["one"]) - tm.assert_series_equal(result, expected["one"], check_names=False) - assert result.name is None - - result = a.dot(b1["one"]) - tm.assert_series_equal(result, expected["one"], check_names=False) - assert result.name is None - - # can pass correct-length arrays - row = a.iloc[0].values - - result = a.dot(row) - expected = a.dot(a.iloc[0]) - tm.assert_series_equal(result, expected) - - with pytest.raises(ValueError, match="Dot product shape mismatch"): - a.dot(row[:-1]) - - a = np.random.rand(1, 5) - b = np.random.rand(5, 1) - A = DataFrame(a) - - # TODO(wesm): unused - B = DataFrame(b) # noqa - - # it works - result = A.dot(b) - - # unaligned - df = DataFrame(np.random.randn(3, 4), index=[1, 2, 3], columns=range(4)) - df2 = DataFrame(np.random.randn(5, 3), index=range(5), columns=[1, 2, 3]) - - with pytest.raises(ValueError, match="aligned"): - df.dot(df2) - def test_matmul(self): # matmul test is for GH 10259 a = DataFrame( diff --git a/pandas/tests/generic/methods/test_dot.py b/pandas/tests/generic/methods/test_dot.py new file mode 100644 index 0000000000000..8c63538999f5b --- /dev/null +++ b/pandas/tests/generic/methods/test_dot.py @@ -0,0 +1,128 @@ +import numpy as np +import pytest + +from pandas import DataFrame, Series +import pandas._testing as tm + + +class DotSharedTests: + @pytest.fixture + def obj(self): + raise NotImplementedError + + @pytest.fixture + def other(self) -> DataFrame: + """ + other is a DataFrame that is indexed so that obj.dot(other) is valid + """ + raise NotImplementedError + + @pytest.fixture + def expected(self, obj, other) -> DataFrame: + """ + The expected result of obj.dot(other) + """ + raise NotImplementedError + + @classmethod + def reduced_dim_assert(cls, result, expected): + """ + Assertion about results with 1 fewer dimension that self.obj + """ + raise NotImplementedError + + def test_dot_equiv_values_dot(self, obj, other, expected): + # `expected` is constructed from obj.values.dot(other.values) + result = obj.dot(other) + tm.assert_equal(result, expected) + + def test_dot_2d_ndarray(self, obj, other, expected): + # Check ndarray argument; in this case we get matching values, + # but index/columns may not match + result = obj.dot(other.values) + assert np.all(result == expected.values) + + def test_dot_1d_ndarray(self, obj, expected): + # can pass correct-length array + row = obj.iloc[0] if obj.ndim == 2 else obj + + result = obj.dot(row.values) + expected = obj.dot(row) + self.reduced_dim_assert(result, expected) + + def test_dot_series(self, obj, other, expected): + # Check series argument + result = obj.dot(other["1"]) + self.reduced_dim_assert(result, expected["1"]) + + def test_dot_series_alignment(self, obj, other, expected): + result = obj.dot(other.iloc[::-1]["1"]) + self.reduced_dim_assert(result, expected["1"]) + + def test_dot_aligns(self, obj, other, expected): + # Check index alignment + other2 = other.iloc[::-1] + result = obj.dot(other2) + tm.assert_equal(result, expected) + + def test_dot_shape_mismatch(self, obj): + msg = r"Dot product shape mismatch" + # exception raised is of type Exception + with pytest.raises(Exception, match=msg): + obj.dot(obj.values[:3]) + + def test_dot_misaligned(self, obj, other): + msg = "matrices are not aligned" + with pytest.raises(ValueError, match=msg): + obj.dot(other.T) + + +class TestSeriesDot(DotSharedTests): + @pytest.fixture + def obj(self): + return Series(np.random.randn(4), index=["p", "q", "r", "s"]) + + @pytest.fixture + def other(self): + return DataFrame( + np.random.randn(3, 4), index=["1", "2", "3"], columns=["p", "q", "r", "s"] + ).T + + @pytest.fixture + def expected(self, obj, other): + return Series(np.dot(obj.values, other.values), index=other.columns) + + @classmethod + def reduced_dim_assert(cls, result, expected): + """ + Assertion about results with 1 fewer dimension that self.obj + """ + tm.assert_almost_equal(result, expected) + + +class TestDataFrameDot(DotSharedTests): + @pytest.fixture + def obj(self): + return DataFrame( + np.random.randn(3, 4), index=["a", "b", "c"], columns=["p", "q", "r", "s"] + ) + + @pytest.fixture + def other(self): + return DataFrame( + np.random.randn(4, 2), index=["p", "q", "r", "s"], columns=["1", "2"] + ) + + @pytest.fixture + def expected(self, obj, other): + return DataFrame( + np.dot(obj.values, other.values), index=obj.index, columns=other.columns + ) + + @classmethod + def reduced_dim_assert(cls, result, expected): + """ + Assertion about results with 1 fewer dimension that self.obj + """ + tm.assert_series_equal(result, expected, check_names=False) + assert result.name is None diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index 149d0aae8ab99..ab8618eb0a7d4 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -17,38 +17,6 @@ def test_prod_numpy16_bug(self): assert not isinstance(result, Series) - def test_dot(self): - a = Series(np.random.randn(4), index=["p", "q", "r", "s"]) - b = DataFrame( - np.random.randn(3, 4), index=["1", "2", "3"], columns=["p", "q", "r", "s"] - ).T - - result = a.dot(b) - expected = Series(np.dot(a.values, b.values), index=["1", "2", "3"]) - tm.assert_series_equal(result, expected) - - # Check index alignment - b2 = b.reindex(index=reversed(b.index)) - result = a.dot(b) - tm.assert_series_equal(result, expected) - - # Check ndarray argument - result = a.dot(b.values) - assert np.all(result == expected.values) - tm.assert_almost_equal(a.dot(b["2"].values), expected["2"]) - - # Check series argument - tm.assert_almost_equal(a.dot(b["1"]), expected["1"]) - tm.assert_almost_equal(a.dot(b2["1"]), expected["1"]) - - msg = r"Dot product shape mismatch, \(4,\) vs \(3,\)" - # exception raised is of type Exception - with pytest.raises(Exception, match=msg): - a.dot(a.values[:3]) - msg = "matrices are not aligned" - with pytest.raises(ValueError, match=msg): - a.dot(b.T) - def test_matmul(self): # matmul test is for GH #10259 a = Series(np.random.randn(4), index=["p", "q", "r", "s"]) From f3963a301569ce27b53987fd2a70d41d469bffc4 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 1 Apr 2020 13:07:31 -0700 Subject: [PATCH 2/3] Update pandas/tests/generic/methods/test_dot.py Co-Authored-By: MomIsBestFriend <50263213+MomIsBestFriend@users.noreply.github.com> --- pandas/tests/generic/methods/test_dot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/generic/methods/test_dot.py b/pandas/tests/generic/methods/test_dot.py index 8c63538999f5b..ecbec6b06e923 100644 --- a/pandas/tests/generic/methods/test_dot.py +++ b/pandas/tests/generic/methods/test_dot.py @@ -66,7 +66,7 @@ def test_dot_aligns(self, obj, other, expected): tm.assert_equal(result, expected) def test_dot_shape_mismatch(self, obj): - msg = r"Dot product shape mismatch" + msg = "Dot product shape mismatch" # exception raised is of type Exception with pytest.raises(Exception, match=msg): obj.dot(obj.values[:3]) From 08ba91bc6fdc158b7f5ed04f1829540154d85204 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 10 Apr 2020 11:12:18 -0700 Subject: [PATCH 3/3] remove unused import --- pandas/core/internals/blocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 75c935cdf2e60..80573f32b936e 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -8,7 +8,7 @@ from pandas._libs import NaT, algos as libalgos, lib, writers import pandas._libs.internals as libinternals -from pandas._libs.tslibs import Timedelta, conversion +from pandas._libs.tslibs import conversion from pandas._libs.tslibs.timezones import tz_compare from pandas._typing import ArrayLike from pandas.util._validators import validate_bool_kwarg