diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index ab3316e7fca4c..0e779ff470fcc 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -710,6 +710,7 @@ Numeric ^^^^^^^ - Bug in :meth:`DataFrame.corr` where numerical precision errors resulted in correlations above ``1.0`` (:issue:`61120`) - Bug in :meth:`DataFrame.quantile` where the column type was not preserved when ``numeric_only=True`` with a list-like ``q`` produced an empty result (:issue:`59035`) +- Bug in :meth:`Series.dot` returning ``object`` dtype for :class:`ArrowDtype` and nullable-dtype data (:issue:`61375`) - Bug in ``np.matmul`` with :class:`Index` inputs raising a ``TypeError`` (:issue:`57079`) Conversion diff --git a/pandas/core/series.py b/pandas/core/series.py index d6a982c65e9fd..5ed094349caaa 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -2951,8 +2951,9 @@ def dot(self, other: AnyArrayLike | DataFrame) -> Series | np.ndarray: ) if isinstance(other, ABCDataFrame): + common_type = find_common_type([self.dtypes] + list(other.dtypes)) return self._constructor( - np.dot(lvals, rvals), index=other.columns, copy=False + np.dot(lvals, rvals), index=other.columns, copy=False, dtype=common_type ).__finalize__(self, method="dot") elif isinstance(other, Series): return np.dot(lvals, rvals) diff --git a/pandas/tests/frame/methods/test_dot.py b/pandas/tests/frame/methods/test_dot.py index 3e01f67c8794b..b365ceb2ab61c 100644 --- a/pandas/tests/frame/methods/test_dot.py +++ b/pandas/tests/frame/methods/test_dot.py @@ -153,3 +153,19 @@ def test_arrow_dtype(dtype, exp_dtype): expected = DataFrame([[1, 2], [3, 4], [5, 6]], dtype=exp_dtype) tm.assert_frame_equal(result, expected) + + +@pytest.mark.parametrize( + "dtype,exp_dtype", + [("Float32", "Float64"), ("Int16", "Int32"), ("float[pyarrow]", "double[pyarrow]")], +) +def test_arrow_dtype_series(dtype, exp_dtype): + pytest.importorskip("pyarrow") + + cols = ["a", "b"] + series_a = Series([1, 2], index=cols, dtype="int32") + df_b = DataFrame([[1, 0], [0, 1]], index=cols, dtype=dtype) + result = series_a.dot(df_b) + expected = Series([1, 2], dtype=exp_dtype) + + tm.assert_series_equal(result, expected)