diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 9a6455d4d012f..852d24a3d1c4e 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -171,7 +171,7 @@ MultiIndex I/O ^^^ -- +- Bug in :meth:`DataFrame.to_stata` where no error is raised if the :class:`DataFrame` contains ``-np.inf`` (:issue:`45350`) - Period diff --git a/pandas/io/stata.py b/pandas/io/stata.py index 4a50a3dabe5e7..e0a070f051534 100644 --- a/pandas/io/stata.py +++ b/pandas/io/stata.py @@ -625,12 +625,12 @@ def _cast_to_stata_types(data: DataFrame) -> DataFrame: if data[col].max() >= 2 ** 53 or data[col].min() <= -(2 ** 53): ws = precision_loss_doc.format("int64", "float64") elif dtype in (np.float32, np.float64): - value = data[col].max() - if np.isinf(value): + if np.isinf(data[col]).any(): raise ValueError( - f"Column {col} has a maximum value of infinity which is outside " - "the range supported by Stata." + f"Column {col} contains infinity or -infinity" + "which is outside the range supported by Stata." ) + value = data[col].max() if dtype == np.float32 and value > float32_max: data[col] = data[col].astype(np.float64) elif dtype == np.float64: diff --git a/pandas/tests/io/test_stata.py b/pandas/tests/io/test_stata.py index f0fd391c2a9c4..4b6643cfa3903 100644 --- a/pandas/tests/io/test_stata.py +++ b/pandas/tests/io/test_stata.py @@ -1473,15 +1473,6 @@ def test_out_of_range_double(self): with tm.ensure_clean() as path: df.to_stata(path) - df.loc[2, "ColumnTooBig"] = np.inf - msg = ( - "Column ColumnTooBig has a maximum value of infinity which is outside " - "the range supported by Stata" - ) - with pytest.raises(ValueError, match=msg): - with tm.ensure_clean() as path: - df.to_stata(path) - def test_out_of_range_float(self): original = DataFrame( { @@ -1507,14 +1498,17 @@ def test_out_of_range_float(self): original["ColumnTooBig"] = original["ColumnTooBig"].astype(np.float64) tm.assert_frame_equal(original, reread.set_index("index")) - original.loc[2, "ColumnTooBig"] = np.inf + @pytest.mark.parametrize("infval", [np.inf, -np.inf]) + def test_inf(self, infval): + # GH 45350 + df = DataFrame({"WithoutInf": [0.0, 1.0], "WithInf": [2.0, infval]}) msg = ( - "Column ColumnTooBig has a maximum value of infinity which " - "is outside the range supported by Stata" + "Column WithInf contains infinity or -infinity" + "which is outside the range supported by Stata." ) with pytest.raises(ValueError, match=msg): with tm.ensure_clean() as path: - original.to_stata(path) + df.to_stata(path) def test_path_pathlib(self): df = tm.makeDataFrame()