Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0cb9e62

Browse files
authored
Merge pull request#10542 from ahaldane/complex_repr_fix_backport
BUG: complex repr has extra spaces, missing + (1.14 backport)
2 parents843e391 +1239026 commit0cb9e62

File tree

3 files changed

+78
-35
lines changed

3 files changed

+78
-35
lines changed

‎doc/release/1.14.1-notes.rst‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
NumPy 1.14.1 Release Notes
33
==========================
44

5-
This is a bugfix release for some problems found since 1.14.0. The most
6-
important fixes are:
7-
8-
5+
This is a bugfix release for some problems found since 1.14.0. This release
6+
includes fixes to the spacing in the str and repr of complex values.
97

108
The Python versions supported are 2.7 and 3.4 - 3.6. The Python 3.6 wheels
119
available from PIP are built with Python 3.6.2 and should be compatible with

‎numpy/core/arrayprint.py‎

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
9999
100100
Parameters
101101
----------
102-
precision : int, optional
102+
precision : int or None, optional
103103
Number of digits of precision for floating point output (default 8).
104+
May be `None` if `floatmode` is not `fixed`, to print as many digits as
105+
necessary to uniquely specify the value.
104106
threshold : int, optional
105107
Total number of array elements which trigger summarization
106108
rather than full repr (default 1000).
@@ -240,6 +242,8 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
240242
# set the C variable for legacy mode
241243
if_format_options['legacy']=='1.13':
242244
set_legacy_print_mode(113)
245+
# reset the sign option in legacy mode to avoid confusion
246+
_format_options['sign']='-'
243247
elif_format_options['legacy']isFalse:
244248
set_legacy_print_mode(0)
245249

@@ -469,7 +473,7 @@ def array2string(a, max_line_width=None, precision=None,
469473
max_line_width : int, optional
470474
The maximum number of columns the string should span. Newline
471475
characters splits the string appropriately after array elements.
472-
precision : int, optional
476+
precision : int or None, optional
473477
Floating point precision. Default is the current printing
474478
precision (usually 8), which can be altered using `set_printoptions`.
475479
suppress_small : bool, optional
@@ -749,6 +753,13 @@ def recurser(index, hanging_indent, curr_width):
749753
curr_width=line_width)
750754

751755

756+
def_none_or_positive_arg(x,name):
757+
ifxisNone:
758+
return-1
759+
ifx<0:
760+
raiseValueError("{} must be >= 0".format(name))
761+
returnx
762+
752763
classFloatingFormat(object):
753764
""" Formatter for subtypes of np.floating """
754765
def__init__(self,data,precision,floatmode,suppress_small,sign=False,
@@ -759,17 +770,18 @@ def __init__(self, data, precision, floatmode, suppress_small, sign=False,
759770

760771
self._legacy=kwarg.get('legacy',False)
761772
ifself._legacy=='1.13':
762-
sign='-'ifdata.shape== ()else' '
773+
# when not 0d, legacy does not support '-'
774+
ifdata.shape!= ()andsign=='-':
775+
sign=' '
763776

764777
self.floatmode=floatmode
765778
iffloatmode=='unique':
766-
self.precision=-1
779+
self.precision=None
767780
else:
768-
ifprecision<0:
769-
raiseValueError(
770-
"precision must be >= 0 in {} mode".format(floatmode))
771781
self.precision=precision
772782

783+
self.precision=_none_or_positive_arg(self.precision,'precision')
784+
773785
self.suppress_small=suppress_small
774786
self.sign=sign
775787
self.exp_format=False
@@ -812,11 +824,9 @@ def fillFormat(self, data):
812824
self.trim='k'
813825
self.precision=max(len(s)forsinfrac_part)
814826

815-
# for back-compatibility with np 1.13, usetwo spaces and full prec
827+
# for back-compat with np 1.13, use2 spaces & sign and full prec
816828
ifself._legacy=='1.13':
817-
# undo addition of sign pos below
818-
will_add_sign=all(finite_vals>0)andself.sign==' '
819-
self.pad_left=3-will_add_sign
829+
self.pad_left=3
820830
else:
821831
# this should be only 1 or 2. Can be calculated from sign.
822832
self.pad_left=max(len(s)forsinint_part)
@@ -835,7 +845,10 @@ def fillFormat(self, data):
835845
sign=self.sign=='+')
836846
forxinfinite_vals)
837847
int_part,frac_part=zip(*(s.split('.')forsinstrs))
838-
self.pad_left=max(len(s)forsinint_part)
848+
ifself._legacy=='1.13':
849+
self.pad_left=1+max(len(s.lstrip('-+'))forsinint_part)
850+
else:
851+
self.pad_left=max(len(s)forsinint_part)
839852
self.pad_right=max(len(s)forsinfrac_part)
840853
self.exp_size=-1
841854

@@ -847,9 +860,10 @@ def fillFormat(self, data):
847860
self.unique=True
848861
self.trim='.'
849862

850-
# account for sign = ' ' by adding one to pad_left
851-
ifall(finite_vals>=0)andself.sign==' ':
852-
self.pad_left+=1
863+
ifself._legacy!='1.13':
864+
# account for sign = ' ' by adding one to pad_left
865+
ifself.sign==' 'andnotany(np.signbit(finite_vals)):
866+
self.pad_left+=1
853867

854868
# if there are non-finite values, may need to increase pad_left
855869
ifdata.size!=finite_vals.size:
@@ -902,7 +916,6 @@ def __init__(self, *args, **kwargs):
902916
DeprecationWarning,stacklevel=2)
903917
super(LongFloatFormat,self).__init__(*args,**kwargs)
904918

905-
906919
defformat_float_scientific(x,precision=None,unique=True,trim='k',
907920
sign=False,pad_left=None,exp_digits=None):
908921
"""
@@ -915,9 +928,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
915928
----------
916929
x : python float or numpy floating scalar
917930
Value to format.
918-
precision : non-negative integer, optional
919-
Maximum number offractionaldigits to print. May beomitted if
920-
`unique` is `True`, butis required if unique is `False`.
931+
precision : non-negative integer or None, optional
932+
Maximum number of digits to print. May beNone if `unique` is
933+
`True`, butmust be an integer if unique is `False`.
921934
unique : boolean, optional
922935
If `True`, use a digit-generation strategy which gives the shortest
923936
representation which uniquely identifies the floating-point number from
@@ -962,9 +975,9 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
962975
>>> np.format_float_scientific(s, exp_digits=4)
963976
'1.23e+0024'
964977
"""
965-
precision=-1ifprecisionisNoneelseprecision
966-
pad_left=-1ifpad_leftisNoneelsepad_left
967-
exp_digits=-1ifexp_digitsisNoneelseexp_digits
978+
precision=_none_or_positive_arg(precision,'precision')
979+
pad_left=_none_or_positive_arg(pad_left,'pad_left')
980+
exp_digits=_none_or_positive_arg(exp_digits,'exp_digits')
968981
returndragon4_scientific(x,precision=precision,unique=unique,
969982
trim=trim,sign=sign,pad_left=pad_left,
970983
exp_digits=exp_digits)
@@ -982,9 +995,9 @@ def format_float_positional(x, precision=None, unique=True,
982995
----------
983996
x : python float or numpy floating scalar
984997
Value to format.
985-
precision : non-negative integer, optional
986-
Maximum number of digits to print. May beomitted if `unique` is
987-
`True`, butis required if unique is `False`.
998+
precision : non-negative integer or None, optional
999+
Maximum number of digits to print. May beNone if `unique` is
1000+
`True`, butmust be an integer if unique is `False`.
9881001
unique : boolean, optional
9891002
If `True`, use a digit-generation strategy which gives the shortest
9901003
representation which uniquely identifies the floating-point number from
@@ -1035,9 +1048,9 @@ def format_float_positional(x, precision=None, unique=True,
10351048
>>> np.format_float_positional(np.float16(0.3), unique=False, precision=10)
10361049
'0.3000488281'
10371050
"""
1038-
precision=-1ifprecisionisNoneelseprecision
1039-
pad_left=-1ifpad_leftisNoneelsepad_left
1040-
pad_right=-1ifpad_rightisNoneelsepad_right
1051+
precision=_none_or_positive_arg(precision,'precision')
1052+
pad_left=_none_or_positive_arg(pad_left,'pad_left')
1053+
pad_right=_none_or_positive_arg(pad_right,'pad_right')
10411054
returndragon4_positional(x,precision=precision,unique=unique,
10421055
fractional=fractional,trim=trim,
10431056
sign=sign,pad_left=pad_left,
@@ -1075,15 +1088,25 @@ def __init__(self, x, precision, floatmode, suppress_small,
10751088
ifisinstance(sign,bool):
10761089
sign='+'ifsignelse'-'
10771090

1078-
self.real_format=FloatingFormat(x.real,precision,floatmode,
1091+
floatmode_real=floatmode_imag=floatmode
1092+
ifkwarg.get('legacy',False)=='1.13':
1093+
floatmode_real='maxprec_equal'
1094+
floatmode_imag='maxprec'
1095+
1096+
self.real_format=FloatingFormat(x.real,precision,floatmode_real,
10791097
suppress_small,sign=sign,**kwarg)
1080-
self.imag_format=FloatingFormat(x.imag,precision,floatmode,
1098+
self.imag_format=FloatingFormat(x.imag,precision,floatmode_imag,
10811099
suppress_small,sign='+',**kwarg)
10821100

10831101
def__call__(self,x):
10841102
r=self.real_format(x.real)
10851103
i=self.imag_format(x.imag)
1086-
returnr+i+'j'
1104+
1105+
# add the 'j' before the terminal whitespace in i
1106+
sp=len(i.rstrip())
1107+
i=i[:sp]+'j'+i[sp:]
1108+
1109+
returnr+i
10871110

10881111
# for back-compatibility, we keep the classes for each complex type too
10891112
classComplexFormat(ComplexFloatingFormat):

‎numpy/core/tests/test_arrayprint.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,28 +433,41 @@ def test_bool_spacing(self):
433433
deftest_sign_spacing(self):
434434
a=np.arange(4.)
435435
b=np.array([1.234e9])
436+
c=np.array([1.0+1.0j,1.123456789+1.123456789j],dtype='c16')
436437

437438
assert_equal(repr(a),'array([0., 1., 2., 3.])')
438439
assert_equal(repr(np.array(1.)),'array(1.)')
439440
assert_equal(repr(b),'array([1.234e+09])')
440441
assert_equal(repr(np.array([0.])),'array([0.])')
442+
assert_equal(repr(c),
443+
"array([1. +1.j , 1.12345679+1.12345679j])")
444+
assert_equal(repr(np.array([0.,-0.])),'array([ 0., -0.])')
441445

442446
np.set_printoptions(sign=' ')
443447
assert_equal(repr(a),'array([ 0., 1., 2., 3.])')
444448
assert_equal(repr(np.array(1.)),'array( 1.)')
445449
assert_equal(repr(b),'array([ 1.234e+09])')
450+
assert_equal(repr(c),
451+
"array([ 1. +1.j , 1.12345679+1.12345679j])")
452+
assert_equal(repr(np.array([0.,-0.])),'array([ 0., -0.])')
446453

447454
np.set_printoptions(sign='+')
448455
assert_equal(repr(a),'array([+0., +1., +2., +3.])')
449456
assert_equal(repr(np.array(1.)),'array(+1.)')
450457
assert_equal(repr(b),'array([+1.234e+09])')
458+
assert_equal(repr(c),
459+
"array([+1. +1.j , +1.12345679+1.12345679j])")
451460

452461
np.set_printoptions(legacy='1.13')
453462
assert_equal(repr(a),'array([ 0., 1., 2., 3.])')
454463
assert_equal(repr(b),'array([ 1.23400000e+09])')
455464
assert_equal(repr(-b),'array([ -1.23400000e+09])')
456465
assert_equal(repr(np.array(1.)),'array(1.0)')
457466
assert_equal(repr(np.array([0.])),'array([ 0.])')
467+
assert_equal(repr(c),
468+
"array([ 1.00000000+1.j , 1.12345679+1.12345679j])")
469+
# gh-10383
470+
assert_equal(str(np.array([-1.,10])),"[ -1. 10.]")
458471

459472
assert_raises(TypeError,np.set_printoptions,wrongarg=True)
460473

@@ -478,6 +491,7 @@ def test_floatmode(self):
478491
0.0862072768214508,0.39112753029631175],
479492
dtype=np.float64)
480493
z=np.arange(6,dtype=np.float16)/10
494+
c=np.array([1.0+1.0j,1.123456789+1.123456789j],dtype='c16')
481495

482496
# also make sure 1e23 is right (is between two fp numbers)
483497
w=np.array(['1e{}'.format(i)foriinrange(25)],dtype=np.float64)
@@ -503,6 +517,8 @@ def test_floatmode(self):
503517
" 1.e+16, 1.e+17, 1.e+18, 1.e+19, 1.e+20, 1.e+21, 1.e+22, 1.e+23,\n"
504518
" 1.e+24])")
505519
assert_equal(repr(wp),"array([1.234e+001, 1.000e+002, 1.000e+123])")
520+
assert_equal(repr(c),
521+
"array([1. +1.j , 1.123456789+1.123456789j])")
506522

507523
# maxprec mode, precision=8
508524
np.set_printoptions(floatmode='maxprec',precision=8)
@@ -517,6 +533,8 @@ def test_floatmode(self):
517533
assert_equal(repr(w[::5]),
518534
"array([1.e+00, 1.e+05, 1.e+10, 1.e+15, 1.e+20])")
519535
assert_equal(repr(wp),"array([1.234e+001, 1.000e+002, 1.000e+123])")
536+
assert_equal(repr(c),
537+
"array([1. +1.j , 1.12345679+1.12345679j])")
520538

521539
# fixed mode, precision=4
522540
np.set_printoptions(floatmode='fixed',precision=4)
@@ -531,6 +549,8 @@ def test_floatmode(self):
531549
"array([1.0000e+00, 1.0000e+05, 1.0000e+10, 1.0000e+15, 1.0000e+20])")
532550
assert_equal(repr(wp),"array([1.2340e+001, 1.0000e+002, 1.0000e+123])")
533551
assert_equal(repr(np.zeros(3)),"array([0.0000, 0.0000, 0.0000])")
552+
assert_equal(repr(c),
553+
"array([1.0000+1.0000j, 1.1235+1.1235j])")
534554
# for larger precision, representation error becomes more apparent:
535555
np.set_printoptions(floatmode='fixed',precision=8)
536556
assert_equal(repr(z),
@@ -550,6 +570,8 @@ def test_floatmode(self):
550570
assert_equal(repr(w[::5]),
551571
"array([1.e+00, 1.e+05, 1.e+10, 1.e+15, 1.e+20])")
552572
assert_equal(repr(wp),"array([1.234e+001, 1.000e+002, 1.000e+123])")
573+
assert_equal(repr(c),
574+
"array([1.00000000+1.00000000j, 1.12345679+1.12345679j])")
553575

554576
deftest_legacy_mode_scalars(self):
555577
# in legacy mode, str of floats get truncated, and complex scalars

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp