From 95d66f0e17c12a1ad661ad68c4fb49eadcf4b578 Mon Sep 17 00:00:00 2001 From: Ming Li Date: Thu, 21 Jun 2018 20:39:13 +0100 Subject: [PATCH 1/7] Ax = (x.T * A.T).T = (x * A.T).T --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 2f762dff4aeab..ca4ecf58b808e 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -2066,7 +2066,7 @@ def __matmul__(self, other): def __rmatmul__(self, other): """ Matrix multiplication using binary `@` operator in Python>=3.5 """ - return self.dot(other) + return self.dot(np.transpose(other)).T @Substitution(klass='Series') @Appender(base._shared_docs['searchsorted']) From 1cad8bb86a2f21dcff8a2257d858f2f2d53ebfdb Mon Sep 17 00:00:00 2001 From: Ming Li Date: Thu, 21 Jun 2018 20:40:50 +0100 Subject: [PATCH 2/7] add test case matrix series __rmatmul__ --- pandas/tests/series/test_analytics.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index b9c7b837b8b81..0d70007dc0fcf 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -854,6 +854,11 @@ def test_matmul(self): expected = np.dot(a.values, a.values) assert_almost_equal(result, expected) + # np.array (matrix) @ Series (__rmatmul__) + result = operator.matmul(b.T.values, a) + expected = np.dot(b.T.values, a.values) + assert_almost_equal(result, expected) + # mixed dtype DataFrame @ Series a['p'] = int(a.p) result = operator.matmul(b.T, a) From 5e4e9f3e05dda85de8cc144f668f3cdfa0755a07 Mon Sep 17 00:00:00 2001 From: Ming Li Date: Thu, 21 Jun 2018 21:11:27 +0100 Subject: [PATCH 3/7] no need to transpose 0D vector --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index ca4ecf58b808e..a608db806d20b 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -2066,7 +2066,7 @@ def __matmul__(self, other): def __rmatmul__(self, other): """ Matrix multiplication using binary `@` operator in Python>=3.5 """ - return self.dot(np.transpose(other)).T + return self.dot(np.transpose(other)) @Substitution(klass='Series') @Appender(base._shared_docs['searchsorted']) From 3904d94fb7c244c7c797bcdd99da11194bcbfcfd Mon Sep 17 00:00:00 2001 From: Ming Li Date: Thu, 21 Jun 2018 21:11:40 +0100 Subject: [PATCH 4/7] add issue number --- pandas/tests/series/test_analytics.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index 0d70007dc0fcf..f2778163ef342 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -854,6 +854,7 @@ def test_matmul(self): expected = np.dot(a.values, a.values) assert_almost_equal(result, expected) + # GH 21530 # np.array (matrix) @ Series (__rmatmul__) result = operator.matmul(b.T.values, a) expected = np.dot(b.T.values, a.values) From 662c0ff481ea66d7d40430ef7a771f8d0fece1de Mon Sep 17 00:00:00 2001 From: Ming Li Date: Thu, 21 Jun 2018 22:12:49 +0100 Subject: [PATCH 5/7] add whatsnew --- doc/source/whatsnew/v0.24.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index fd34424dedc52..aadb380a816f4 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -183,7 +183,7 @@ Offsets Numeric ^^^^^^^ -- +- Bug in :class:`Series` ``__rmatmul__`` doesn't support matrix vector multiplication (:issue:`21530`) - - From 3db45a9cf671589e668f8a47618f4c6e248d6168 Mon Sep 17 00:00:00 2001 From: Ming Li Date: Fri, 22 Jun 2018 13:12:43 +0100 Subject: [PATCH 6/7] update tests for both lists and numpy array 1D and 2D --- pandas/tests/series/test_analytics.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index f2778163ef342..8d14509f61bdb 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -849,17 +849,30 @@ def test_matmul(self): expected = np.dot(a.values, a.values) assert_almost_equal(result, expected) - # np.array @ Series (__rmatmul__) + # GH 21530 + # vector (1D np.array) @ Series (__rmatmul__) result = operator.matmul(a.values, a) expected = np.dot(a.values, a.values) assert_almost_equal(result, expected) # GH 21530 - # np.array (matrix) @ Series (__rmatmul__) + # vector (1D list) @ Series (__rmatmul__) + result = operator.matmul(a.tolist(), a) + expected = np.dot(a.values, a.values) + assert_almost_equal(result, expected) + + # GH 21530 + # matrix (2D np.array) @ Series (__rmatmul__) result = operator.matmul(b.T.values, a) expected = np.dot(b.T.values, a.values) assert_almost_equal(result, expected) + # GH 21530 + # matrix (2D nested lists) @ Series (__rmatmul__) + result = operator.matmul(b.T.tolist(), a) + expected = np.dot(b.T.values, a.values) + assert_almost_equal(result, expected) + # mixed dtype DataFrame @ Series a['p'] = int(a.p) result = operator.matmul(b.T, a) From d5a0d284877a0ebda7bf083d28d051197ee8ead1 Mon Sep 17 00:00:00 2001 From: Ming Li Date: Fri, 22 Jun 2018 13:46:30 +0100 Subject: [PATCH 7/7] dataframe no tolist method --- pandas/tests/series/test_analytics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index 8d14509f61bdb..36342b5ba4ee1 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -857,7 +857,7 @@ def test_matmul(self): # GH 21530 # vector (1D list) @ Series (__rmatmul__) - result = operator.matmul(a.tolist(), a) + result = operator.matmul(a.values.tolist(), a) expected = np.dot(a.values, a.values) assert_almost_equal(result, expected) @@ -869,7 +869,7 @@ def test_matmul(self): # GH 21530 # matrix (2D nested lists) @ Series (__rmatmul__) - result = operator.matmul(b.T.tolist(), a) + result = operator.matmul(b.T.values.tolist(), a) expected = np.dot(b.T.values, a.values) assert_almost_equal(result, expected)