diff --git a/pandas/core/generic.py b/pandas/core/generic.py index f32b347de32c3..a9fe349d53e4d 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3302,7 +3302,7 @@ def to_csv( path_or_buf: FilePath | WriteBuffer[bytes] | WriteBuffer[str] | None = None, sep: str = ",", na_rep: str = "", - float_format: str | None = None, + float_format: str | Callable | None = None, columns: Sequence[Hashable] | None = None, header: bool_t | list[str] = True, index: bool_t = True, @@ -3341,8 +3341,9 @@ def to_csv( String of length 1. Field delimiter for the output file. na_rep : str, default '' Missing data representation. - float_format : str, default None - Format string for floating point numbers. + float_format : str, Callable, default None + Format string for floating point numbers. If a Callable is given, it takes + precedence over other numeric formatting parameters, like decimal. columns : sequence, optional Columns to write. header : bool or list of str, default True diff --git a/pandas/tests/frame/methods/test_to_csv.py b/pandas/tests/frame/methods/test_to_csv.py index f1ecad2f711bc..df7bc04202e39 100644 --- a/pandas/tests/frame/methods/test_to_csv.py +++ b/pandas/tests/frame/methods/test_to_csv.py @@ -833,6 +833,18 @@ def test_to_csv_float_format(self): ) tm.assert_frame_equal(rs, xp) + def test_to_csv_float_format_over_decimal(self): + # GH#47436 + df = DataFrame({"a": [0.5, 1.0]}) + result = df.to_csv( + decimal=",", + float_format=lambda x: np.format_float_positional(x, trim="-"), + index=False, + ) + expected_rows = ["a", "0.5", "1"] + expected = tm.convert_rows_list_to_csv_str(expected_rows) + assert result == expected + def test_to_csv_unicodewriter_quoting(self): df = DataFrame({"A": [1, 2, 3], "B": ["foo", "bar", "baz"]})