Skip to content

Commit 82ce975

Browse files
Khor Chean Weimroeschke
Khor Chean Wei
andauthored
The indexes of DataFrame.describe(percentiles=[0.29, 0.57, 0.58]) are incorrect (#48298)
* add test * add test * add * Update doc/source/whatsnew/v1.6.0.rst Co-authored-by: Matthew Roeschke <[email protected]> * add Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 2d8d313 commit 82ce975

File tree

3 files changed

+28
-17
lines changed

3 files changed

+28
-17
lines changed

doc/source/whatsnew/v1.6.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ Indexing
154154
^^^^^^^^
155155
- Bug in :meth:`DataFrame.reindex` filling with wrong values when indexing columns and index for ``uint`` dtypes (:issue:`48184`)
156156
- Bug in :meth:`DataFrame.reindex` casting dtype to ``object`` when :class:`DataFrame` has single extension array column when re-indexing ``columns`` and ``index`` (:issue:`48190`)
157-
-
157+
- Bug in :func:`~DataFrame.describe` when formatting percentiles in the resulting index showed more decimals than needed (:issue:`46362`)
158158

159159
Missing
160160
^^^^^^^

pandas/io/formats/format.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1720,11 +1720,12 @@ def format_percentiles(
17201720
raise ValueError("percentiles should all be in the interval [0,1]")
17211721

17221722
percentiles = 100 * percentiles
1723+
percentiles_round_type = percentiles.round().astype(int)
17231724

1724-
int_idx = np.isclose(percentiles.astype(int), percentiles)
1725+
int_idx = np.isclose(percentiles_round_type, percentiles)
17251726

17261727
if np.all(int_idx):
1727-
out = percentiles.astype(int).astype(str)
1728+
out = percentiles_round_type.astype(str)
17281729
return [i + "%" for i in out]
17291730

17301731
unique_pcts = np.unique(percentiles)
@@ -1737,7 +1738,7 @@ def format_percentiles(
17371738
).astype(int)
17381739
prec = max(1, prec)
17391740
out = np.empty_like(percentiles, dtype=object)
1740-
out[int_idx] = percentiles[int_idx].astype(int).astype(str)
1741+
out[int_idx] = percentiles[int_idx].round().astype(int).astype(str)
17411742

17421743
out[~int_idx] = percentiles[~int_idx].round(prec).astype(str)
17431744
return [i + "%" for i in out]

pandas/tests/io/formats/test_format.py

+23-13
Original file line numberDiff line numberDiff line change
@@ -3306,24 +3306,34 @@ def test_nat_representations(self):
33063306
assert f(NaT) == "NaT"
33073307

33083308

3309-
def test_format_percentiles():
3310-
result = fmt.format_percentiles([0.01999, 0.02001, 0.5, 0.666666, 0.9999])
3311-
expected = ["1.999%", "2.001%", "50%", "66.667%", "99.99%"]
3309+
@pytest.mark.parametrize(
3310+
"percentiles, expected",
3311+
[
3312+
(
3313+
[0.01999, 0.02001, 0.5, 0.666666, 0.9999],
3314+
["1.999%", "2.001%", "50%", "66.667%", "99.99%"],
3315+
),
3316+
(
3317+
[0, 0.5, 0.02001, 0.5, 0.666666, 0.9999],
3318+
["0%", "50%", "2.0%", "50%", "66.67%", "99.99%"],
3319+
),
3320+
([0.281, 0.29, 0.57, 0.58], ["28.1%", "29%", "57%", "58%"]),
3321+
([0.28, 0.29, 0.57, 0.58], ["28%", "29%", "57%", "58%"]),
3322+
],
3323+
)
3324+
def test_format_percentiles(percentiles, expected):
3325+
result = fmt.format_percentiles(percentiles)
33123326
assert result == expected
33133327

3314-
result = fmt.format_percentiles([0, 0.5, 0.02001, 0.5, 0.666666, 0.9999])
3315-
expected = ["0%", "50%", "2.0%", "50%", "66.67%", "99.99%"]
3316-
assert result == expected
33173328

3329+
@pytest.mark.parametrize(
3330+
"percentiles",
3331+
[([0.1, np.nan, 0.5]), ([-0.001, 0.1, 0.5]), ([2, 0.1, 0.5]), ([0.1, 0.5, "a"])],
3332+
)
3333+
def test_error_format_percentiles(percentiles):
33183334
msg = r"percentiles should all be in the interval \[0,1\]"
33193335
with pytest.raises(ValueError, match=msg):
3320-
fmt.format_percentiles([0.1, np.nan, 0.5])
3321-
with pytest.raises(ValueError, match=msg):
3322-
fmt.format_percentiles([-0.001, 0.1, 0.5])
3323-
with pytest.raises(ValueError, match=msg):
3324-
fmt.format_percentiles([2, 0.1, 0.5])
3325-
with pytest.raises(ValueError, match=msg):
3326-
fmt.format_percentiles([0.1, 0.5, "a"])
3336+
fmt.format_percentiles(percentiles)
33273337

33283338

33293339
def test_format_percentiles_integer_idx():

0 commit comments

Comments
 (0)