summaryrefslogtreecommitdiff
path: root/numpy/core/arrayprint.py
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2018-01-28 18:31:00 -0700
committerGitHub <noreply@github.com>2018-01-28 18:31:00 -0700
commit4e175ab8634597f595215f83b3c779cc4e0e7eaa (patch)
tree2d67dd17f690593910ce137c27ff8a7213c78e59 /numpy/core/arrayprint.py
parentab51f997645c8b1f6a432442c8a999911a8eff25 (diff)
parent652892bf387344db6cd729fd5acbe4ac0c15b69c (diff)
downloadnumpy-4e175ab8634597f595215f83b3c779cc4e0e7eaa.tar.gz
Merge pull request #10361 from ahaldane/complex_repr_fix
BUG: complex repr has extra spaces, missing +
Diffstat (limited to 'numpy/core/arrayprint.py')
-rw-r--r--numpy/core/arrayprint.py85
1 files changed, 54 insertions, 31 deletions
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index 369b3a913..472318098 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -99,8 +99,10 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
Parameters
----------
- precision : int, optional
+ precision : int or None, optional
Number of digits of precision for floating point output (default 8).
+ May be `None` if `floatmode` is not `fixed`, to print as many digits as
+ necessary to uniquely specify the value.
threshold : int, optional
Total number of array elements which trigger summarization
rather than full repr (default 1000).
@@ -240,6 +242,8 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
# set the C variable for legacy mode
if _format_options['legacy'] == '1.13':
set_legacy_print_mode(113)
+ # reset the sign option in legacy mode to avoid confusion
+ _format_options['sign'] = '-'
elif _format_options['legacy'] is False:
set_legacy_print_mode(0)
@@ -502,7 +506,7 @@ def array2string(a, max_line_width=None, precision=None,
max_line_width : int, optional
The maximum number of columns the string should span. Newline
characters splits the string appropriately after array elements.
- precision : int, optional
+ precision : int or None, optional
Floating point precision. Default is the current printing
precision (usually 8), which can be altered using `set_printoptions`.
suppress_small : bool, optional
@@ -782,6 +786,13 @@ def _formatArray(a, format_function, line_width, next_line_prefix,
curr_width=line_width)
+def _none_or_positive_arg(x, name):
+ if x is None:
+ return -1
+ if x < 0:
+ raise ValueError("{} must be >= 0".format(name))
+ return x
+
class FloatingFormat(object):
""" Formatter for subtypes of np.floating """
def __init__(self, data, precision, floatmode, suppress_small, sign=False,
@@ -792,17 +803,18 @@ class FloatingFormat(object):
self._legacy = kwarg.get('legacy', False)
if self._legacy == '1.13':
- sign = '-' if data.shape == () else ' '
+ # when not 0d, legacy does not support '-'
+ if data.shape != () and sign == '-':
+ sign = ' '
self.floatmode = floatmode
if floatmode == 'unique':
- self.precision = -1
+ self.precision = None
else:
- if precision < 0:
- raise ValueError(
- "precision must be >= 0 in {} mode".format(floatmode))
self.precision = precision
+ self.precision = _none_or_positive_arg(self.precision, 'precision')
+
self.suppress_small = suppress_small
self.sign = sign
self.exp_format = False
@@ -845,11 +857,9 @@ class FloatingFormat(object):
self.trim = 'k'
self.precision = max(len(s) for s in frac_part)
- # for back-compatibility with np 1.13, use two spaces and full prec
+ # for back-compat with np 1.13, use 2 spaces & sign and full prec
if self._legacy == '1.13':
- # undo addition of sign pos below
- will_add_sign = all(finite_vals > 0) and self.sign == ' '
- self.pad_left = 3 - will_add_sign
+ self.pad_left = 3
else:
# this should be only 1 or 2. Can be calculated from sign.
self.pad_left = max(len(s) for s in int_part)
@@ -868,7 +878,10 @@ class FloatingFormat(object):
sign=self.sign == '+')
for x in finite_vals)
int_part, frac_part = zip(*(s.split('.') for s in strs))
- self.pad_left = max(len(s) for s in int_part)
+ if self._legacy == '1.13':
+ self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part)
+ else:
+ self.pad_left = max(len(s) for s in int_part)
self.pad_right = max(len(s) for s in frac_part)
self.exp_size = -1
@@ -880,9 +893,10 @@ class FloatingFormat(object):
self.unique = True
self.trim = '.'
- # account for sign = ' ' by adding one to pad_left
- if all(finite_vals >= 0) and self.sign == ' ':
- self.pad_left += 1
+ if self._legacy != '1.13':
+ # account for sign = ' ' by adding one to pad_left
+ if self.sign == ' ' and not any(np.signbit(finite_vals)):
+ self.pad_left += 1
# if there are non-finite values, may need to increase pad_left
if data.size != finite_vals.size:
@@ -935,7 +949,6 @@ class LongFloatFormat(FloatingFormat):
DeprecationWarning, stacklevel=2)
super(LongFloatFormat, self).__init__(*args, **kwargs)
-
def format_float_scientific(x, precision=None, unique=True, trim='k',
sign=False, pad_left=None, exp_digits=None):
"""
@@ -948,9 +961,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
----------
x : python float or numpy floating scalar
Value to format.
- precision : non-negative integer, optional
- Maximum number of fractional digits to print. May be omitted if
- `unique` is `True`, but is required if unique is `False`.
+ precision : non-negative integer or None, optional
+ Maximum number of digits to print. May be None if `unique` is
+ `True`, but must be an integer if unique is `False`.
unique : boolean, optional
If `True`, use a digit-generation strategy which gives the shortest
representation which uniquely identifies the floating-point number from
@@ -995,9 +1008,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
>>> np.format_float_scientific(s, exp_digits=4)
'1.23e+0024'
"""
- precision = -1 if precision is None else precision
- pad_left = -1 if pad_left is None else pad_left
- exp_digits = -1 if exp_digits is None else exp_digits
+ precision = _none_or_positive_arg(precision, 'precision')
+ pad_left = _none_or_positive_arg(pad_left, 'pad_left')
+ exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits')
return dragon4_scientific(x, precision=precision, unique=unique,
trim=trim, sign=sign, pad_left=pad_left,
exp_digits=exp_digits)
@@ -1015,9 +1028,9 @@ def format_float_positional(x, precision=None, unique=True,
----------
x : python float or numpy floating scalar
Value to format.
- precision : non-negative integer, optional
- Maximum number of digits to print. May be omitted if `unique` is
- `True`, but is required if unique is `False`.
+ precision : non-negative integer or None, optional
+ Maximum number of digits to print. May be None if `unique` is
+ `True`, but must be an integer if unique is `False`.
unique : boolean, optional
If `True`, use a digit-generation strategy which gives the shortest
representation which uniquely identifies the floating-point number from
@@ -1068,9 +1081,9 @@ def format_float_positional(x, precision=None, unique=True,
>>> np.format_float_positional(np.float16(0.3), unique=False, precision=10)
'0.3000488281'
"""
- precision = -1 if precision is None else precision
- pad_left = -1 if pad_left is None else pad_left
- pad_right = -1 if pad_right is None else pad_right
+ precision = _none_or_positive_arg(precision, 'precision')
+ pad_left = _none_or_positive_arg(pad_left, 'pad_left')
+ pad_right = _none_or_positive_arg(pad_right, 'pad_right')
return dragon4_positional(x, precision=precision, unique=unique,
fractional=fractional, trim=trim,
sign=sign, pad_left=pad_left,
@@ -1108,15 +1121,25 @@ class ComplexFloatingFormat(object):
if isinstance(sign, bool):
sign = '+' if sign else '-'
- self.real_format = FloatingFormat(x.real, precision, floatmode,
+ floatmode_real = floatmode_imag = floatmode
+ if kwarg.get('legacy', False) == '1.13':
+ floatmode_real = 'maxprec_equal'
+ floatmode_imag = 'maxprec'
+
+ self.real_format = FloatingFormat(x.real, precision, floatmode_real,
suppress_small, sign=sign, **kwarg)
- self.imag_format = FloatingFormat(x.imag, precision, floatmode,
+ self.imag_format = FloatingFormat(x.imag, precision, floatmode_imag,
suppress_small, sign='+', **kwarg)
def __call__(self, x):
r = self.real_format(x.real)
i = self.imag_format(x.imag)
- return r + i + 'j'
+
+ # add the 'j' before the terminal whitespace in i
+ sp = len(i.rstrip())
+ i = i[:sp] + 'j' + i[sp:]
+
+ return r + i
# for back-compatibility, we keep the classes for each complex type too
class ComplexFormat(ComplexFloatingFormat):