Skip to content

Fix strange behavior when precision display option is zero (#20359) #35212

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
Jul 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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,7 @@ MultiIndex

I/O
^^^
- Bug in print-out when ``display.precision`` is zero. (:issue:`20359`)
- Bug in :meth:`read_json` where integer overflow was occurring when json contains big number strings. (:issue:`30320`)
- `read_csv` will now raise a ``ValueError`` when the arguments `header` and `prefix` both are not `None`. (:issue:`27394`)
- Bug in :meth:`DataFrame.to_json` was raising ``NotFoundError`` when ``path_or_buf`` was an S3 URI (:issue:`28375`)
Expand Down
17 changes: 11 additions & 6 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -1382,9 +1382,9 @@ def format_values_with(float_format):

if self.fixed_width:
if is_complex:
result = _trim_zeros_complex(values, na_rep)
result = _trim_zeros_complex(values, self.decimal, na_rep)
else:
result = _trim_zeros_float(values, na_rep)
result = _trim_zeros_float(values, self.decimal, na_rep)
return np.asarray(result, dtype="object")

return values
Expand Down Expand Up @@ -1754,19 +1754,21 @@ def just(x):
return result


def _trim_zeros_complex(str_complexes: np.ndarray, na_rep: str = "NaN") -> List[str]:
def _trim_zeros_complex(
str_complexes: np.ndarray, decimal: str = ".", na_rep: str = "NaN"
) -> List[str]:
"""
Separates the real and imaginary parts from the complex number, and
executes the _trim_zeros_float method on each of those.
"""
return [
"".join(_trim_zeros_float(re.split(r"([j+-])", x), na_rep))
"".join(_trim_zeros_float(re.split(r"([j+-])", x), decimal, na_rep))
for x in str_complexes
]


def _trim_zeros_float(
str_floats: Union[np.ndarray, List[str]], na_rep: str = "NaN"
str_floats: Union[np.ndarray, List[str]], decimal: str = ".", na_rep: str = "NaN"
) -> List[str]:
"""
Trims zeros, leaving just one before the decimal points if need be.
Expand All @@ -1778,8 +1780,11 @@ def _is_number(x):

def _cond(values):
finite = [x for x in values if _is_number(x)]
has_decimal = [decimal in x for x in finite]

return (
len(finite) > 0
and all(has_decimal)
and all(x.endswith("0") for x in finite)
and not (any(("e" in x) or ("E" in x) for x in finite))
)
Expand All @@ -1788,7 +1793,7 @@ def _cond(values):
trimmed = [x[:-1] if _is_number(x) else x for x in trimmed]

# leave one 0 after the decimal points if need be.
return [x + "0" if x.endswith(".") and _is_number(x) else x for x in trimmed]
return [x + "0" if x.endswith(decimal) and _is_number(x) else x for x in trimmed]


def _has_names(index: Index) -> bool:
Expand Down
9 changes: 9 additions & 0 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2910,6 +2910,15 @@ def test_format(self):
assert result[0] == " 12.0"
assert result[1] == " 0.0"

def test_output_display_precision_trailing_zeroes(self):
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 also test with the 2 as display.precision (ideally parameterize), but ok to just list a 2nd case if easier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jreback i actually didn’t have time to address the second test but I saw that you merged the PR ald. I assume that means the test is fine. Let me know otherwise.

# Issue #20359: trimming zeros while there is no decimal point

# Happens when display precision is set to zero
with pd.option_context("display.precision", 0):
s = pd.Series([840.0, 4200.0])
expected_output = "0 840\n1 4200\ndtype: float64"
assert str(s) == expected_output

def test_output_significant_digits(self):
# Issue #9764

Expand Down