Skip to content

REF: .dot tests #33214

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

Merged
merged 6 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
53 changes: 0 additions & 53 deletions pandas/tests/frame/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
128 changes: 128 additions & 0 deletions pandas/tests/generic/methods/test_dot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import numpy as np
import pytest

from pandas import DataFrame, Series
import pandas._testing as tm


class DotSharedTests:
@pytest.fixture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make these module level fixtures, having in a class is an anti-patter

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even better is to use the globally defined fixtures (but if hard nbd)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jbrockmendel do we need these class level fixtures like this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for some value of "need". Simon and i do not have a consensus on this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, the reason i question this is that we do not do this anywhere else (except for a PR you just did), and we DO this also in the resample tests. Since we aren't intentionally doing this globally I want to be sure this pattern is a valid / reasonable usecase that simply doesn't fit into our other patterns.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use it a bunch in tests.indexes

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 = "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
32 changes: 0 additions & 32 deletions pandas/tests/series/test_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down