Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/numpy/_core/arrayprint.py: 19%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

604 statements  

1"""Array printing function 

2 

3$Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $ 

4 

5""" 

6__all__ = ["array2string", "array_str", "array_repr", 

7 "set_printoptions", "get_printoptions", "printoptions", 

8 "format_float_positional", "format_float_scientific"] 

9__docformat__ = 'restructuredtext' 

10 

11# 

12# Written by Konrad Hinsen <hinsenk@ere.umontreal.ca> 

13# last revision: 1996-3-13 

14# modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details) 

15# and by Perry Greenfield 2000-4-1 for numarray 

16# and by Travis Oliphant 2005-8-22 for numpy 

17 

18 

19# Note: Both scalartypes.c.src and arrayprint.py implement strs for numpy 

20# scalars but for different purposes. scalartypes.c.src has str/reprs for when 

21# the scalar is printed on its own, while arrayprint.py has strs for when 

22# scalars are printed inside an ndarray. Only the latter strs are currently 

23# user-customizable. 

24 

25import functools 

26import numbers 

27import sys 

28try: 

29 from _thread import get_ident 

30except ImportError: 

31 from _dummy_thread import get_ident 

32 

33import numpy as np 

34from . import numerictypes as _nt 

35from .umath import absolute, isinf, isfinite, isnat 

36from . import multiarray 

37from .multiarray import (array, dragon4_positional, dragon4_scientific, 

38 datetime_as_string, datetime_data, ndarray) 

39from .fromnumeric import any 

40from .numeric import concatenate, asarray, errstate 

41from .numerictypes import (longlong, intc, int_, float64, complex128, 

42 flexible) 

43from .overrides import array_function_dispatch, set_module 

44from .printoptions import format_options 

45import operator 

46import warnings 

47import contextlib 

48 

49 

50def _make_options_dict(precision=None, threshold=None, edgeitems=None, 

51 linewidth=None, suppress=None, nanstr=None, infstr=None, 

52 sign=None, formatter=None, floatmode=None, legacy=None, 

53 override_repr=None): 

54 """ 

55 Make a dictionary out of the non-None arguments, plus conversion of 

56 *legacy* and sanity checks. 

57 """ 

58 

59 options = {k: v for k, v in list(locals().items()) if v is not None} 

60 

61 if suppress is not None: 

62 options['suppress'] = bool(suppress) 

63 

64 modes = ['fixed', 'unique', 'maxprec', 'maxprec_equal'] 

65 if floatmode not in modes + [None]: 

66 raise ValueError("floatmode option must be one of " + 

67 ", ".join('"{}"'.format(m) for m in modes)) 

68 

69 if sign not in [None, '-', '+', ' ']: 

70 raise ValueError("sign option must be one of ' ', '+', or '-'") 

71 

72 if legacy is False: 

73 options['legacy'] = sys.maxsize 

74 elif legacy == False: # noqa: E712 

75 warnings.warn( 

76 f"Passing `legacy={legacy!r}` is deprecated.", 

77 FutureWarning, stacklevel=3 

78 ) 

79 options['legacy'] = sys.maxsize 

80 elif legacy == '1.13': 

81 options['legacy'] = 113 

82 elif legacy == '1.21': 

83 options['legacy'] = 121 

84 elif legacy == '1.25': 

85 options['legacy'] = 125 

86 elif legacy == '2.1': 

87 options['legacy'] = 201 

88 elif legacy is None: 

89 pass # OK, do nothing. 

90 else: 

91 warnings.warn( 

92 "legacy printing option can currently only be '1.13', '1.21', " 

93 "'1.25', '2.1, or `False`", stacklevel=3) 

94 

95 if threshold is not None: 

96 # forbid the bad threshold arg suggested by stack overflow, gh-12351 

97 if not isinstance(threshold, numbers.Number): 

98 raise TypeError("threshold must be numeric") 

99 if np.isnan(threshold): 

100 raise ValueError("threshold must be non-NAN, try " 

101 "sys.maxsize for untruncated representation") 

102 

103 if precision is not None: 

104 # forbid the bad precision arg as suggested by issue #18254 

105 try: 

106 options['precision'] = operator.index(precision) 

107 except TypeError as e: 

108 raise TypeError('precision must be an integer') from e 

109 

110 return options 

111 

112 

113@set_module('numpy') 

114def set_printoptions(precision=None, threshold=None, edgeitems=None, 

115 linewidth=None, suppress=None, nanstr=None, 

116 infstr=None, formatter=None, sign=None, floatmode=None, 

117 *, legacy=None, override_repr=None): 

118 """ 

119 Set printing options. 

120 

121 These options determine the way floating point numbers, arrays and 

122 other NumPy objects are displayed. 

123 

124 Parameters 

125 ---------- 

126 precision : int or None, optional 

127 Number of digits of precision for floating point output (default 8). 

128 May be None if `floatmode` is not `fixed`, to print as many digits as 

129 necessary to uniquely specify the value. 

130 threshold : int, optional 

131 Total number of array elements which trigger summarization 

132 rather than full repr (default 1000). 

133 To always use the full repr without summarization, pass `sys.maxsize`. 

134 edgeitems : int, optional 

135 Number of array items in summary at beginning and end of 

136 each dimension (default 3). 

137 linewidth : int, optional 

138 The number of characters per line for the purpose of inserting 

139 line breaks (default 75). 

140 suppress : bool, optional 

141 If True, always print floating point numbers using fixed point 

142 notation, in which case numbers equal to zero in the current precision 

143 will print as zero. If False, then scientific notation is used when 

144 absolute value of the smallest number is < 1e-4 or the ratio of the 

145 maximum absolute value to the minimum is > 1e3. The default is False. 

146 nanstr : str, optional 

147 String representation of floating point not-a-number (default nan). 

148 infstr : str, optional 

149 String representation of floating point infinity (default inf). 

150 sign : string, either '-', '+', or ' ', optional 

151 Controls printing of the sign of floating-point types. If '+', always 

152 print the sign of positive values. If ' ', always prints a space 

153 (whitespace character) in the sign position of positive values. If 

154 '-', omit the sign character of positive values. (default '-') 

155 

156 .. versionchanged:: 2.0 

157 The sign parameter can now be an integer type, previously 

158 types were floating-point types. 

159 

160 formatter : dict of callables, optional 

161 If not None, the keys should indicate the type(s) that the respective 

162 formatting function applies to. Callables should return a string. 

163 Types that are not specified (by their corresponding keys) are handled 

164 by the default formatters. Individual types for which a formatter 

165 can be set are: 

166 

167 - 'bool' 

168 - 'int' 

169 - 'timedelta' : a `numpy.timedelta64` 

170 - 'datetime' : a `numpy.datetime64` 

171 - 'float' 

172 - 'longfloat' : 128-bit floats 

173 - 'complexfloat' 

174 - 'longcomplexfloat' : composed of two 128-bit floats 

175 - 'numpystr' : types `numpy.bytes_` and `numpy.str_` 

176 - 'object' : `np.object_` arrays 

177 

178 Other keys that can be used to set a group of types at once are: 

179 

180 - 'all' : sets all types 

181 - 'int_kind' : sets 'int' 

182 - 'float_kind' : sets 'float' and 'longfloat' 

183 - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' 

184 - 'str_kind' : sets 'numpystr' 

185 floatmode : str, optional 

186 Controls the interpretation of the `precision` option for 

187 floating-point types. Can take the following values 

188 (default maxprec_equal): 

189 

190 * 'fixed': Always print exactly `precision` fractional digits, 

191 even if this would print more or fewer digits than 

192 necessary to specify the value uniquely. 

193 * 'unique': Print the minimum number of fractional digits necessary 

194 to represent each value uniquely. Different elements may 

195 have a different number of digits. The value of the 

196 `precision` option is ignored. 

197 * 'maxprec': Print at most `precision` fractional digits, but if 

198 an element can be uniquely represented with fewer digits 

199 only print it with that many. 

200 * 'maxprec_equal': Print at most `precision` fractional digits, 

201 but if every element in the array can be uniquely 

202 represented with an equal number of fewer digits, use that 

203 many digits for all elements. 

204 legacy : string or `False`, optional 

205 If set to the string ``'1.13'`` enables 1.13 legacy printing mode. This 

206 approximates numpy 1.13 print output by including a space in the sign 

207 position of floats and different behavior for 0d arrays. This also 

208 enables 1.21 legacy printing mode (described below). 

209 

210 If set to the string ``'1.21'`` enables 1.21 legacy printing mode. This 

211 approximates numpy 1.21 print output of complex structured dtypes 

212 by not inserting spaces after commas that separate fields and after 

213 colons. 

214 

215 If set to ``'1.25'`` approximates printing of 1.25 which mainly means 

216 that numeric scalars are printed without their type information, e.g. 

217 as ``3.0`` rather than ``np.float64(3.0)``. 

218 

219 If set to ``'2.1'``, shape information is not given when arrays are 

220 summarized (i.e., multiple elements replaced with ``...``). 

221 

222 If set to `False`, disables legacy mode. 

223 

224 Unrecognized strings will be ignored with a warning for forward 

225 compatibility. 

226 

227 .. versionchanged:: 1.22.0 

228 .. versionchanged:: 2.2 

229 

230 override_repr: callable, optional 

231 If set a passed function will be used for generating arrays' repr. 

232 Other options will be ignored. 

233 

234 See Also 

235 -------- 

236 get_printoptions, printoptions, array2string 

237 

238 Notes 

239 ----- 

240 `formatter` is always reset with a call to `set_printoptions`. 

241 

242 Use `printoptions` as a context manager to set the values temporarily. 

243 

244 Examples 

245 -------- 

246 Floating point precision can be set: 

247 

248 >>> import numpy as np 

249 >>> np.set_printoptions(precision=4) 

250 >>> np.array([1.123456789]) 

251 [1.1235] 

252 

253 Long arrays can be summarised: 

254 

255 >>> np.set_printoptions(threshold=5) 

256 >>> np.arange(10) 

257 array([0, 1, 2, ..., 7, 8, 9], shape=(10,)) 

258 

259 Small results can be suppressed: 

260 

261 >>> eps = np.finfo(float).eps 

262 >>> x = np.arange(4.) 

263 >>> x**2 - (x + eps)**2 

264 array([-4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00]) 

265 >>> np.set_printoptions(suppress=True) 

266 >>> x**2 - (x + eps)**2 

267 array([-0., -0., 0., 0.]) 

268 

269 A custom formatter can be used to display array elements as desired: 

270 

271 >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)}) 

272 >>> x = np.arange(3) 

273 >>> x 

274 array([int: 0, int: -1, int: -2]) 

275 >>> np.set_printoptions() # formatter gets reset 

276 >>> x 

277 array([0, 1, 2]) 

278 

279 To put back the default options, you can use: 

280 

281 >>> np.set_printoptions(edgeitems=3, infstr='inf', 

282 ... linewidth=75, nanstr='nan', precision=8, 

283 ... suppress=False, threshold=1000, formatter=None) 

284 

285 Also to temporarily override options, use `printoptions` 

286 as a context manager: 

287 

288 >>> with np.printoptions(precision=2, suppress=True, threshold=5): 

289 ... np.linspace(0, 10, 10) 

290 array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ], shape=(10,)) 

291 

292 """ 

293 _set_printoptions(precision, threshold, edgeitems, linewidth, suppress, 

294 nanstr, infstr, formatter, sign, floatmode, 

295 legacy=legacy, override_repr=override_repr) 

296 

297 

298def _set_printoptions(precision=None, threshold=None, edgeitems=None, 

299 linewidth=None, suppress=None, nanstr=None, 

300 infstr=None, formatter=None, sign=None, floatmode=None, 

301 *, legacy=None, override_repr=None): 

302 new_opt = _make_options_dict(precision, threshold, edgeitems, linewidth, 

303 suppress, nanstr, infstr, sign, formatter, 

304 floatmode, legacy) 

305 # formatter and override_repr are always reset 

306 new_opt['formatter'] = formatter 

307 new_opt['override_repr'] = override_repr 

308 

309 updated_opt = format_options.get() | new_opt 

310 updated_opt.update(new_opt) 

311 

312 if updated_opt['legacy'] == 113: 

313 updated_opt['sign'] = '-' 

314 

315 return format_options.set(updated_opt) 

316 

317 

318@set_module('numpy') 

319def get_printoptions(): 

320 """ 

321 Return the current print options. 

322 

323 Returns 

324 ------- 

325 print_opts : dict 

326 Dictionary of current print options with keys 

327 

328 - precision : int 

329 - threshold : int 

330 - edgeitems : int 

331 - linewidth : int 

332 - suppress : bool 

333 - nanstr : str 

334 - infstr : str 

335 - sign : str 

336 - formatter : dict of callables 

337 - floatmode : str 

338 - legacy : str or False 

339 

340 For a full description of these options, see `set_printoptions`. 

341 

342 See Also 

343 -------- 

344 set_printoptions, printoptions 

345 

346 Examples 

347 -------- 

348 >>> import numpy as np 

349 

350 >>> np.get_printoptions() 

351 {'edgeitems': 3, 'threshold': 1000, ..., 'override_repr': None} 

352 

353 >>> np.get_printoptions()['linewidth'] 

354 75 

355 >>> np.set_printoptions(linewidth=100) 

356 >>> np.get_printoptions()['linewidth'] 

357 100 

358 

359 """ 

360 opts = format_options.get().copy() 

361 opts['legacy'] = { 

362 113: '1.13', 121: '1.21', 125: '1.25', sys.maxsize: False, 

363 }[opts['legacy']] 

364 return opts 

365 

366 

367def _get_legacy_print_mode(): 

368 """Return the legacy print mode as an int.""" 

369 return format_options.get()['legacy'] 

370 

371 

372@set_module('numpy') 

373@contextlib.contextmanager 

374def printoptions(*args, **kwargs): 

375 """Context manager for setting print options. 

376 

377 Set print options for the scope of the `with` block, and restore the old 

378 options at the end. See `set_printoptions` for the full description of 

379 available options. 

380 

381 Examples 

382 -------- 

383 >>> import numpy as np 

384 

385 >>> from numpy.testing import assert_equal 

386 >>> with np.printoptions(precision=2): 

387 ... np.array([2.0]) / 3 

388 array([0.67]) 

389 

390 The `as`-clause of the `with`-statement gives the current print options: 

391 

392 >>> with np.printoptions(precision=2) as opts: 

393 ... assert_equal(opts, np.get_printoptions()) 

394 

395 See Also 

396 -------- 

397 set_printoptions, get_printoptions 

398 

399 """ 

400 token = _set_printoptions(*args, **kwargs) 

401 

402 try: 

403 yield get_printoptions() 

404 finally: 

405 format_options.reset(token) 

406 

407 

408def _leading_trailing(a, edgeitems, index=()): 

409 """ 

410 Keep only the N-D corners (leading and trailing edges) of an array. 

411 

412 Should be passed a base-class ndarray, since it makes no guarantees about 

413 preserving subclasses. 

414 """ 

415 axis = len(index) 

416 if axis == a.ndim: 

417 return a[index] 

418 

419 if a.shape[axis] > 2*edgeitems: 

420 return concatenate(( 

421 _leading_trailing(a, edgeitems, index + np.index_exp[:edgeitems]), 

422 _leading_trailing(a, edgeitems, index + np.index_exp[-edgeitems:]) 

423 ), axis=axis) 

424 else: 

425 return _leading_trailing(a, edgeitems, index + np.index_exp[:]) 

426 

427 

428def _object_format(o): 

429 """ Object arrays containing lists should be printed unambiguously """ 

430 if type(o) is list: 

431 fmt = 'list({!r})' 

432 else: 

433 fmt = '{!r}' 

434 return fmt.format(o) 

435 

436def repr_format(x): 

437 if isinstance(x, (np.str_, np.bytes_)): 

438 return repr(x.item()) 

439 return repr(x) 

440 

441def str_format(x): 

442 if isinstance(x, (np.str_, np.bytes_)): 

443 return str(x.item()) 

444 return str(x) 

445 

446def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy, 

447 formatter, **kwargs): 

448 # note: extra arguments in kwargs are ignored 

449 

450 # wrapped in lambdas to avoid taking a code path 

451 # with the wrong type of data 

452 formatdict = { 

453 'bool': lambda: BoolFormat(data), 

454 'int': lambda: IntegerFormat(data, sign), 

455 'float': lambda: FloatingFormat( 

456 data, precision, floatmode, suppress, sign, legacy=legacy), 

457 'longfloat': lambda: FloatingFormat( 

458 data, precision, floatmode, suppress, sign, legacy=legacy), 

459 'complexfloat': lambda: ComplexFloatingFormat( 

460 data, precision, floatmode, suppress, sign, legacy=legacy), 

461 'longcomplexfloat': lambda: ComplexFloatingFormat( 

462 data, precision, floatmode, suppress, sign, legacy=legacy), 

463 'datetime': lambda: DatetimeFormat(data, legacy=legacy), 

464 'timedelta': lambda: TimedeltaFormat(data), 

465 'object': lambda: _object_format, 

466 'void': lambda: str_format, 

467 'numpystr': lambda: repr_format} 

468 

469 # we need to wrap values in `formatter` in a lambda, so that the interface 

470 # is the same as the above values. 

471 def indirect(x): 

472 return lambda: x 

473 

474 if formatter is not None: 

475 fkeys = [k for k in formatter.keys() if formatter[k] is not None] 

476 if 'all' in fkeys: 

477 for key in formatdict.keys(): 

478 formatdict[key] = indirect(formatter['all']) 

479 if 'int_kind' in fkeys: 

480 for key in ['int']: 

481 formatdict[key] = indirect(formatter['int_kind']) 

482 if 'float_kind' in fkeys: 

483 for key in ['float', 'longfloat']: 

484 formatdict[key] = indirect(formatter['float_kind']) 

485 if 'complex_kind' in fkeys: 

486 for key in ['complexfloat', 'longcomplexfloat']: 

487 formatdict[key] = indirect(formatter['complex_kind']) 

488 if 'str_kind' in fkeys: 

489 formatdict['numpystr'] = indirect(formatter['str_kind']) 

490 for key in formatdict.keys(): 

491 if key in fkeys: 

492 formatdict[key] = indirect(formatter[key]) 

493 

494 return formatdict 

495 

496def _get_format_function(data, **options): 

497 """ 

498 find the right formatting function for the dtype_ 

499 """ 

500 dtype_ = data.dtype 

501 dtypeobj = dtype_.type 

502 formatdict = _get_formatdict(data, **options) 

503 if dtypeobj is None: 

504 return formatdict["numpystr"]() 

505 elif issubclass(dtypeobj, _nt.bool): 

506 return formatdict['bool']() 

507 elif issubclass(dtypeobj, _nt.integer): 

508 if issubclass(dtypeobj, _nt.timedelta64): 

509 return formatdict['timedelta']() 

510 else: 

511 return formatdict['int']() 

512 elif issubclass(dtypeobj, _nt.floating): 

513 if issubclass(dtypeobj, _nt.longdouble): 

514 return formatdict['longfloat']() 

515 else: 

516 return formatdict['float']() 

517 elif issubclass(dtypeobj, _nt.complexfloating): 

518 if issubclass(dtypeobj, _nt.clongdouble): 

519 return formatdict['longcomplexfloat']() 

520 else: 

521 return formatdict['complexfloat']() 

522 elif issubclass(dtypeobj, (_nt.str_, _nt.bytes_)): 

523 return formatdict['numpystr']() 

524 elif issubclass(dtypeobj, _nt.datetime64): 

525 return formatdict['datetime']() 

526 elif issubclass(dtypeobj, _nt.object_): 

527 return formatdict['object']() 

528 elif issubclass(dtypeobj, _nt.void): 

529 if dtype_.names is not None: 

530 return StructuredVoidFormat.from_data(data, **options) 

531 else: 

532 return formatdict['void']() 

533 else: 

534 return formatdict['numpystr']() 

535 

536 

537def _recursive_guard(fillvalue='...'): 

538 """ 

539 Like the python 3.2 reprlib.recursive_repr, but forwards *args and **kwargs 

540 

541 Decorates a function such that if it calls itself with the same first 

542 argument, it returns `fillvalue` instead of recursing. 

543 

544 Largely copied from reprlib.recursive_repr 

545 """ 

546 

547 def decorating_function(f): 

548 repr_running = set() 

549 

550 @functools.wraps(f) 

551 def wrapper(self, *args, **kwargs): 

552 key = id(self), get_ident() 

553 if key in repr_running: 

554 return fillvalue 

555 repr_running.add(key) 

556 try: 

557 return f(self, *args, **kwargs) 

558 finally: 

559 repr_running.discard(key) 

560 

561 return wrapper 

562 

563 return decorating_function 

564 

565 

566# gracefully handle recursive calls, when object arrays contain themselves 

567@_recursive_guard() 

568def _array2string(a, options, separator=' ', prefix=""): 

569 # The formatter __init__s in _get_format_function cannot deal with 

570 # subclasses yet, and we also need to avoid recursion issues in 

571 # _formatArray with subclasses which return 0d arrays in place of scalars 

572 data = asarray(a) 

573 if a.shape == (): 

574 a = data 

575 

576 if a.size > options['threshold']: 

577 summary_insert = "..." 

578 data = _leading_trailing(data, options['edgeitems']) 

579 else: 

580 summary_insert = "" 

581 

582 # find the right formatting function for the array 

583 format_function = _get_format_function(data, **options) 

584 

585 # skip over "[" 

586 next_line_prefix = " " 

587 # skip over array( 

588 next_line_prefix += " "*len(prefix) 

589 

590 lst = _formatArray(a, format_function, options['linewidth'], 

591 next_line_prefix, separator, options['edgeitems'], 

592 summary_insert, options['legacy']) 

593 return lst 

594 

595 

596def _array2string_dispatcher( 

597 a, max_line_width=None, precision=None, 

598 suppress_small=None, separator=None, prefix=None, 

599 style=None, formatter=None, threshold=None, 

600 edgeitems=None, sign=None, floatmode=None, suffix=None, 

601 *, legacy=None): 

602 return (a,) 

603 

604 

605@array_function_dispatch(_array2string_dispatcher, module='numpy') 

606def array2string(a, max_line_width=None, precision=None, 

607 suppress_small=None, separator=' ', prefix="", 

608 style=np._NoValue, formatter=None, threshold=None, 

609 edgeitems=None, sign=None, floatmode=None, suffix="", 

610 *, legacy=None): 

611 """ 

612 Return a string representation of an array. 

613 

614 Parameters 

615 ---------- 

616 a : ndarray 

617 Input array. 

618 max_line_width : int, optional 

619 Inserts newlines if text is longer than `max_line_width`. 

620 Defaults to ``numpy.get_printoptions()['linewidth']``. 

621 precision : int or None, optional 

622 Floating point precision. 

623 Defaults to ``numpy.get_printoptions()['precision']``. 

624 suppress_small : bool, optional 

625 Represent numbers "very close" to zero as zero; default is False. 

626 Very close is defined by precision: if the precision is 8, e.g., 

627 numbers smaller (in absolute value) than 5e-9 are represented as 

628 zero. 

629 Defaults to ``numpy.get_printoptions()['suppress']``. 

630 separator : str, optional 

631 Inserted between elements. 

632 prefix : str, optional 

633 suffix : str, optional 

634 The length of the prefix and suffix strings are used to respectively 

635 align and wrap the output. An array is typically printed as:: 

636 

637 prefix + array2string(a) + suffix 

638 

639 The output is left-padded by the length of the prefix string, and 

640 wrapping is forced at the column ``max_line_width - len(suffix)``. 

641 It should be noted that the content of prefix and suffix strings are 

642 not included in the output. 

643 style : _NoValue, optional 

644 Has no effect, do not use. 

645 

646 .. deprecated:: 1.14.0 

647 formatter : dict of callables, optional 

648 If not None, the keys should indicate the type(s) that the respective 

649 formatting function applies to. Callables should return a string. 

650 Types that are not specified (by their corresponding keys) are handled 

651 by the default formatters. Individual types for which a formatter 

652 can be set are: 

653 

654 - 'bool' 

655 - 'int' 

656 - 'timedelta' : a `numpy.timedelta64` 

657 - 'datetime' : a `numpy.datetime64` 

658 - 'float' 

659 - 'longfloat' : 128-bit floats 

660 - 'complexfloat' 

661 - 'longcomplexfloat' : composed of two 128-bit floats 

662 - 'void' : type `numpy.void` 

663 - 'numpystr' : types `numpy.bytes_` and `numpy.str_` 

664 

665 Other keys that can be used to set a group of types at once are: 

666 

667 - 'all' : sets all types 

668 - 'int_kind' : sets 'int' 

669 - 'float_kind' : sets 'float' and 'longfloat' 

670 - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat' 

671 - 'str_kind' : sets 'numpystr' 

672 threshold : int, optional 

673 Total number of array elements which trigger summarization 

674 rather than full repr. 

675 Defaults to ``numpy.get_printoptions()['threshold']``. 

676 edgeitems : int, optional 

677 Number of array items in summary at beginning and end of 

678 each dimension. 

679 Defaults to ``numpy.get_printoptions()['edgeitems']``. 

680 sign : string, either '-', '+', or ' ', optional 

681 Controls printing of the sign of floating-point types. If '+', always 

682 print the sign of positive values. If ' ', always prints a space 

683 (whitespace character) in the sign position of positive values. If 

684 '-', omit the sign character of positive values. 

685 Defaults to ``numpy.get_printoptions()['sign']``. 

686 

687 .. versionchanged:: 2.0 

688 The sign parameter can now be an integer type, previously 

689 types were floating-point types. 

690 

691 floatmode : str, optional 

692 Controls the interpretation of the `precision` option for 

693 floating-point types. 

694 Defaults to ``numpy.get_printoptions()['floatmode']``. 

695 Can take the following values: 

696 

697 - 'fixed': Always print exactly `precision` fractional digits, 

698 even if this would print more or fewer digits than 

699 necessary to specify the value uniquely. 

700 - 'unique': Print the minimum number of fractional digits necessary 

701 to represent each value uniquely. Different elements may 

702 have a different number of digits. The value of the 

703 `precision` option is ignored. 

704 - 'maxprec': Print at most `precision` fractional digits, but if 

705 an element can be uniquely represented with fewer digits 

706 only print it with that many. 

707 - 'maxprec_equal': Print at most `precision` fractional digits, 

708 but if every element in the array can be uniquely 

709 represented with an equal number of fewer digits, use that 

710 many digits for all elements. 

711 legacy : string or `False`, optional 

712 If set to the string ``'1.13'`` enables 1.13 legacy printing mode. This 

713 approximates numpy 1.13 print output by including a space in the sign 

714 position of floats and different behavior for 0d arrays. If set to 

715 `False`, disables legacy mode. Unrecognized strings will be ignored 

716 with a warning for forward compatibility. 

717 

718 Returns 

719 ------- 

720 array_str : str 

721 String representation of the array. 

722 

723 Raises 

724 ------ 

725 TypeError 

726 if a callable in `formatter` does not return a string. 

727 

728 See Also 

729 -------- 

730 array_str, array_repr, set_printoptions, get_printoptions 

731 

732 Notes 

733 ----- 

734 If a formatter is specified for a certain type, the `precision` keyword is 

735 ignored for that type. 

736 

737 This is a very flexible function; `array_repr` and `array_str` are using 

738 `array2string` internally so keywords with the same name should work 

739 identically in all three functions. 

740 

741 Examples 

742 -------- 

743 >>> import numpy as np 

744 >>> x = np.array([1e-16,1,2,3]) 

745 >>> np.array2string(x, precision=2, separator=',', 

746 ... suppress_small=True) 

747 '[0.,1.,2.,3.]' 

748 

749 >>> x = np.arange(3.) 

750 >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x}) 

751 '[0.00 1.00 2.00]' 

752 

753 >>> x = np.arange(3) 

754 >>> np.array2string(x, formatter={'int':lambda x: hex(x)}) 

755 '[0x0 0x1 0x2]' 

756 

757 """ 

758 

759 overrides = _make_options_dict(precision, threshold, edgeitems, 

760 max_line_width, suppress_small, None, None, 

761 sign, formatter, floatmode, legacy) 

762 options = format_options.get().copy() 

763 options.update(overrides) 

764 

765 if options['legacy'] <= 113: 

766 if style is np._NoValue: 

767 style = repr 

768 

769 if a.shape == () and a.dtype.names is None: 

770 return style(a.item()) 

771 elif style is not np._NoValue: 

772 # Deprecation 11-9-2017 v1.14 

773 warnings.warn("'style' argument is deprecated and no longer functional" 

774 " except in 1.13 'legacy' mode", 

775 DeprecationWarning, stacklevel=2) 

776 

777 if options['legacy'] > 113: 

778 options['linewidth'] -= len(suffix) 

779 

780 # treat as a null array if any of shape elements == 0 

781 if a.size == 0: 

782 return "[]" 

783 

784 return _array2string(a, options, separator, prefix) 

785 

786 

787def _extendLine(s, line, word, line_width, next_line_prefix, legacy): 

788 needs_wrap = len(line) + len(word) > line_width 

789 if legacy > 113: 

790 # don't wrap lines if it won't help 

791 if len(line) <= len(next_line_prefix): 

792 needs_wrap = False 

793 

794 if needs_wrap: 

795 s += line.rstrip() + "\n" 

796 line = next_line_prefix 

797 line += word 

798 return s, line 

799 

800 

801def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy): 

802 """ 

803 Extends line with nicely formatted (possibly multi-line) string ``word``. 

804 """ 

805 words = word.splitlines() 

806 if len(words) == 1 or legacy <= 113: 

807 return _extendLine(s, line, word, line_width, next_line_prefix, legacy) 

808 

809 max_word_length = max(len(word) for word in words) 

810 if (len(line) + max_word_length > line_width and 

811 len(line) > len(next_line_prefix)): 

812 s += line.rstrip() + '\n' 

813 line = next_line_prefix + words[0] 

814 indent = next_line_prefix 

815 else: 

816 indent = len(line)*' ' 

817 line += words[0] 

818 

819 for word in words[1::]: 

820 s += line.rstrip() + '\n' 

821 line = indent + word 

822 

823 suffix_length = max_word_length - len(words[-1]) 

824 line += suffix_length*' ' 

825 

826 return s, line 

827 

828def _formatArray(a, format_function, line_width, next_line_prefix, 

829 separator, edge_items, summary_insert, legacy): 

830 """formatArray is designed for two modes of operation: 

831 

832 1. Full output 

833 

834 2. Summarized output 

835 

836 """ 

837 def recurser(index, hanging_indent, curr_width): 

838 """ 

839 By using this local function, we don't need to recurse with all the 

840 arguments. Since this function is not created recursively, the cost is 

841 not significant 

842 """ 

843 axis = len(index) 

844 axes_left = a.ndim - axis 

845 

846 if axes_left == 0: 

847 return format_function(a[index]) 

848 

849 # when recursing, add a space to align with the [ added, and reduce the 

850 # length of the line by 1 

851 next_hanging_indent = hanging_indent + ' ' 

852 if legacy <= 113: 

853 next_width = curr_width 

854 else: 

855 next_width = curr_width - len(']') 

856 

857 a_len = a.shape[axis] 

858 show_summary = summary_insert and 2*edge_items < a_len 

859 if show_summary: 

860 leading_items = edge_items 

861 trailing_items = edge_items 

862 else: 

863 leading_items = 0 

864 trailing_items = a_len 

865 

866 # stringify the array with the hanging indent on the first line too 

867 s = '' 

868 

869 # last axis (rows) - wrap elements if they would not fit on one line 

870 if axes_left == 1: 

871 # the length up until the beginning of the separator / bracket 

872 if legacy <= 113: 

873 elem_width = curr_width - len(separator.rstrip()) 

874 else: 

875 elem_width = curr_width - max( 

876 len(separator.rstrip()), len(']') 

877 ) 

878 

879 line = hanging_indent 

880 for i in range(leading_items): 

881 word = recurser(index + (i,), next_hanging_indent, next_width) 

882 s, line = _extendLine_pretty( 

883 s, line, word, elem_width, hanging_indent, legacy) 

884 line += separator 

885 

886 if show_summary: 

887 s, line = _extendLine( 

888 s, line, summary_insert, elem_width, hanging_indent, legacy 

889 ) 

890 if legacy <= 113: 

891 line += ", " 

892 else: 

893 line += separator 

894 

895 for i in range(trailing_items, 1, -1): 

896 word = recurser(index + (-i,), next_hanging_indent, next_width) 

897 s, line = _extendLine_pretty( 

898 s, line, word, elem_width, hanging_indent, legacy) 

899 line += separator 

900 

901 if legacy <= 113: 

902 # width of the separator is not considered on 1.13 

903 elem_width = curr_width 

904 word = recurser(index + (-1,), next_hanging_indent, next_width) 

905 s, line = _extendLine_pretty( 

906 s, line, word, elem_width, hanging_indent, legacy) 

907 

908 s += line 

909 

910 # other axes - insert newlines between rows 

911 else: 

912 s = '' 

913 line_sep = separator.rstrip() + '\n'*(axes_left - 1) 

914 

915 for i in range(leading_items): 

916 nested = recurser( 

917 index + (i,), next_hanging_indent, next_width 

918 ) 

919 s += hanging_indent + nested + line_sep 

920 

921 if show_summary: 

922 if legacy <= 113: 

923 # trailing space, fixed nbr of newlines, 

924 # and fixed separator 

925 s += hanging_indent + summary_insert + ", \n" 

926 else: 

927 s += hanging_indent + summary_insert + line_sep 

928 

929 for i in range(trailing_items, 1, -1): 

930 nested = recurser(index + (-i,), next_hanging_indent, 

931 next_width) 

932 s += hanging_indent + nested + line_sep 

933 

934 nested = recurser(index + (-1,), next_hanging_indent, next_width) 

935 s += hanging_indent + nested 

936 

937 # remove the hanging indent, and wrap in [] 

938 s = '[' + s[len(hanging_indent):] + ']' 

939 return s 

940 

941 try: 

942 # invoke the recursive part with an initial index and prefix 

943 return recurser(index=(), 

944 hanging_indent=next_line_prefix, 

945 curr_width=line_width) 

946 finally: 

947 # recursive closures have a cyclic reference to themselves, which 

948 # requires gc to collect (gh-10620). To avoid this problem, for 

949 # performance and PyPy friendliness, we break the cycle: 

950 recurser = None 

951 

952def _none_or_positive_arg(x, name): 

953 if x is None: 

954 return -1 

955 if x < 0: 

956 raise ValueError("{} must be >= 0".format(name)) 

957 return x 

958 

959class FloatingFormat: 

960 """ Formatter for subtypes of np.floating """ 

961 def __init__(self, data, precision, floatmode, suppress_small, sign=False, 

962 *, legacy=None): 

963 # for backcompatibility, accept bools 

964 if isinstance(sign, bool): 

965 sign = '+' if sign else '-' 

966 

967 self._legacy = legacy 

968 if self._legacy <= 113: 

969 # when not 0d, legacy does not support '-' 

970 if data.shape != () and sign == '-': 

971 sign = ' ' 

972 

973 self.floatmode = floatmode 

974 if floatmode == 'unique': 

975 self.precision = None 

976 else: 

977 self.precision = precision 

978 

979 self.precision = _none_or_positive_arg(self.precision, 'precision') 

980 

981 self.suppress_small = suppress_small 

982 self.sign = sign 

983 self.exp_format = False 

984 self.large_exponent = False 

985 self.fillFormat(data) 

986 

987 def fillFormat(self, data): 

988 # only the finite values are used to compute the number of digits 

989 finite_vals = data[isfinite(data)] 

990 

991 # choose exponential mode based on the non-zero finite values: 

992 abs_non_zero = absolute(finite_vals[finite_vals != 0]) 

993 if len(abs_non_zero) != 0: 

994 max_val = np.max(abs_non_zero) 

995 min_val = np.min(abs_non_zero) 

996 with errstate(over='ignore'): # division can overflow 

997 if max_val >= 1.e8 or (not self.suppress_small and 

998 (min_val < 0.0001 or max_val/min_val > 1000.)): 

999 self.exp_format = True 

1000 

1001 # do a first pass of printing all the numbers, to determine sizes 

1002 if len(finite_vals) == 0: 

1003 self.pad_left = 0 

1004 self.pad_right = 0 

1005 self.trim = '.' 

1006 self.exp_size = -1 

1007 self.unique = True 

1008 self.min_digits = None 

1009 elif self.exp_format: 

1010 trim, unique = '.', True 

1011 if self.floatmode == 'fixed' or self._legacy <= 113: 

1012 trim, unique = 'k', False 

1013 strs = (dragon4_scientific(x, precision=self.precision, 

1014 unique=unique, trim=trim, sign=self.sign == '+') 

1015 for x in finite_vals) 

1016 frac_strs, _, exp_strs = zip(*(s.partition('e') for s in strs)) 

1017 int_part, frac_part = zip(*(s.split('.') for s in frac_strs)) 

1018 self.exp_size = max(len(s) for s in exp_strs) - 1 

1019 

1020 self.trim = 'k' 

1021 self.precision = max(len(s) for s in frac_part) 

1022 self.min_digits = self.precision 

1023 self.unique = unique 

1024 

1025 # for back-compat with np 1.13, use 2 spaces & sign and full prec 

1026 if self._legacy <= 113: 

1027 self.pad_left = 3 

1028 else: 

1029 # this should be only 1 or 2. Can be calculated from sign. 

1030 self.pad_left = max(len(s) for s in int_part) 

1031 # pad_right is only needed for nan length calculation 

1032 self.pad_right = self.exp_size + 2 + self.precision 

1033 else: 

1034 trim, unique = '.', True 

1035 if self.floatmode == 'fixed': 

1036 trim, unique = 'k', False 

1037 strs = (dragon4_positional(x, precision=self.precision, 

1038 fractional=True, 

1039 unique=unique, trim=trim, 

1040 sign=self.sign == '+') 

1041 for x in finite_vals) 

1042 int_part, frac_part = zip(*(s.split('.') for s in strs)) 

1043 if self._legacy <= 113: 

1044 self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part) 

1045 else: 

1046 self.pad_left = max(len(s) for s in int_part) 

1047 self.pad_right = max(len(s) for s in frac_part) 

1048 self.exp_size = -1 

1049 self.unique = unique 

1050 

1051 if self.floatmode in ['fixed', 'maxprec_equal']: 

1052 self.precision = self.min_digits = self.pad_right 

1053 self.trim = 'k' 

1054 else: 

1055 self.trim = '.' 

1056 self.min_digits = 0 

1057 

1058 if self._legacy > 113: 

1059 # account for sign = ' ' by adding one to pad_left 

1060 if self.sign == ' ' and not any(np.signbit(finite_vals)): 

1061 self.pad_left += 1 

1062 

1063 # if there are non-finite values, may need to increase pad_left 

1064 if data.size != finite_vals.size: 

1065 neginf = self.sign != '-' or any(data[isinf(data)] < 0) 

1066 offset = self.pad_right + 1 # +1 for decimal pt 

1067 current_options = format_options.get() 

1068 self.pad_left = max( 

1069 self.pad_left, len(current_options['nanstr']) - offset, 

1070 len(current_options['infstr']) + neginf - offset 

1071 ) 

1072 

1073 def __call__(self, x): 

1074 if not np.isfinite(x): 

1075 with errstate(invalid='ignore'): 

1076 current_options = format_options.get() 

1077 if np.isnan(x): 

1078 sign = '+' if self.sign == '+' else '' 

1079 ret = sign + current_options['nanstr'] 

1080 else: # isinf 

1081 sign = '-' if x < 0 else '+' if self.sign == '+' else '' 

1082 ret = sign + current_options['infstr'] 

1083 return ' '*( 

1084 self.pad_left + self.pad_right + 1 - len(ret) 

1085 ) + ret 

1086 

1087 if self.exp_format: 

1088 return dragon4_scientific(x, 

1089 precision=self.precision, 

1090 min_digits=self.min_digits, 

1091 unique=self.unique, 

1092 trim=self.trim, 

1093 sign=self.sign == '+', 

1094 pad_left=self.pad_left, 

1095 exp_digits=self.exp_size) 

1096 else: 

1097 return dragon4_positional(x, 

1098 precision=self.precision, 

1099 min_digits=self.min_digits, 

1100 unique=self.unique, 

1101 fractional=True, 

1102 trim=self.trim, 

1103 sign=self.sign == '+', 

1104 pad_left=self.pad_left, 

1105 pad_right=self.pad_right) 

1106 

1107 

1108@set_module('numpy') 

1109def format_float_scientific(x, precision=None, unique=True, trim='k', 

1110 sign=False, pad_left=None, exp_digits=None, 

1111 min_digits=None): 

1112 """ 

1113 Format a floating-point scalar as a decimal string in scientific notation. 

1114 

1115 Provides control over rounding, trimming and padding. Uses and assumes 

1116 IEEE unbiased rounding. Uses the "Dragon4" algorithm. 

1117 

1118 Parameters 

1119 ---------- 

1120 x : python float or numpy floating scalar 

1121 Value to format. 

1122 precision : non-negative integer or None, optional 

1123 Maximum number of digits to print. May be None if `unique` is 

1124 `True`, but must be an integer if unique is `False`. 

1125 unique : boolean, optional 

1126 If `True`, use a digit-generation strategy which gives the shortest 

1127 representation which uniquely identifies the floating-point number from 

1128 other values of the same type, by judicious rounding. If `precision` 

1129 is given fewer digits than necessary can be printed. If `min_digits` 

1130 is given more can be printed, in which cases the last digit is rounded 

1131 with unbiased rounding. 

1132 If `False`, digits are generated as if printing an infinite-precision 

1133 value and stopping after `precision` digits, rounding the remaining 

1134 value with unbiased rounding 

1135 trim : one of 'k', '.', '0', '-', optional 

1136 Controls post-processing trimming of trailing digits, as follows: 

1137 

1138 * 'k' : keep trailing zeros, keep decimal point (no trimming) 

1139 * '.' : trim all trailing zeros, leave decimal point 

1140 * '0' : trim all but the zero before the decimal point. Insert the 

1141 zero if it is missing. 

1142 * '-' : trim trailing zeros and any trailing decimal point 

1143 sign : boolean, optional 

1144 Whether to show the sign for positive values. 

1145 pad_left : non-negative integer, optional 

1146 Pad the left side of the string with whitespace until at least that 

1147 many characters are to the left of the decimal point. 

1148 exp_digits : non-negative integer, optional 

1149 Pad the exponent with zeros until it contains at least this 

1150 many digits. If omitted, the exponent will be at least 2 digits. 

1151 min_digits : non-negative integer or None, optional 

1152 Minimum number of digits to print. This only has an effect for 

1153 `unique=True`. In that case more digits than necessary to uniquely 

1154 identify the value may be printed and rounded unbiased. 

1155 

1156 .. versionadded:: 1.21.0 

1157 

1158 Returns 

1159 ------- 

1160 rep : string 

1161 The string representation of the floating point value 

1162 

1163 See Also 

1164 -------- 

1165 format_float_positional 

1166 

1167 Examples 

1168 -------- 

1169 >>> import numpy as np 

1170 >>> np.format_float_scientific(np.float32(np.pi)) 

1171 '3.1415927e+00' 

1172 >>> s = np.float32(1.23e24) 

1173 >>> np.format_float_scientific(s, unique=False, precision=15) 

1174 '1.230000071797338e+24' 

1175 >>> np.format_float_scientific(s, exp_digits=4) 

1176 '1.23e+0024' 

1177 """ 

1178 precision = _none_or_positive_arg(precision, 'precision') 

1179 pad_left = _none_or_positive_arg(pad_left, 'pad_left') 

1180 exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits') 

1181 min_digits = _none_or_positive_arg(min_digits, 'min_digits') 

1182 if min_digits > 0 and precision > 0 and min_digits > precision: 

1183 raise ValueError("min_digits must be less than or equal to precision") 

1184 return dragon4_scientific(x, precision=precision, unique=unique, 

1185 trim=trim, sign=sign, pad_left=pad_left, 

1186 exp_digits=exp_digits, min_digits=min_digits) 

1187 

1188 

1189@set_module('numpy') 

1190def format_float_positional(x, precision=None, unique=True, 

1191 fractional=True, trim='k', sign=False, 

1192 pad_left=None, pad_right=None, min_digits=None): 

1193 """ 

1194 Format a floating-point scalar as a decimal string in positional notation. 

1195 

1196 Provides control over rounding, trimming and padding. Uses and assumes 

1197 IEEE unbiased rounding. Uses the "Dragon4" algorithm. 

1198 

1199 Parameters 

1200 ---------- 

1201 x : python float or numpy floating scalar 

1202 Value to format. 

1203 precision : non-negative integer or None, optional 

1204 Maximum number of digits to print. May be None if `unique` is 

1205 `True`, but must be an integer if unique is `False`. 

1206 unique : boolean, optional 

1207 If `True`, use a digit-generation strategy which gives the shortest 

1208 representation which uniquely identifies the floating-point number from 

1209 other values of the same type, by judicious rounding. If `precision` 

1210 is given fewer digits than necessary can be printed, or if `min_digits` 

1211 is given more can be printed, in which cases the last digit is rounded 

1212 with unbiased rounding. 

1213 If `False`, digits are generated as if printing an infinite-precision 

1214 value and stopping after `precision` digits, rounding the remaining 

1215 value with unbiased rounding 

1216 fractional : boolean, optional 

1217 If `True`, the cutoffs of `precision` and `min_digits` refer to the 

1218 total number of digits after the decimal point, including leading 

1219 zeros. 

1220 If `False`, `precision` and `min_digits` refer to the total number of 

1221 significant digits, before or after the decimal point, ignoring leading 

1222 zeros. 

1223 trim : one of 'k', '.', '0', '-', optional 

1224 Controls post-processing trimming of trailing digits, as follows: 

1225 

1226 * 'k' : keep trailing zeros, keep decimal point (no trimming) 

1227 * '.' : trim all trailing zeros, leave decimal point 

1228 * '0' : trim all but the zero before the decimal point. Insert the 

1229 zero if it is missing. 

1230 * '-' : trim trailing zeros and any trailing decimal point 

1231 sign : boolean, optional 

1232 Whether to show the sign for positive values. 

1233 pad_left : non-negative integer, optional 

1234 Pad the left side of the string with whitespace until at least that 

1235 many characters are to the left of the decimal point. 

1236 pad_right : non-negative integer, optional 

1237 Pad the right side of the string with whitespace until at least that 

1238 many characters are to the right of the decimal point. 

1239 min_digits : non-negative integer or None, optional 

1240 Minimum number of digits to print. Only has an effect if `unique=True` 

1241 in which case additional digits past those necessary to uniquely 

1242 identify the value may be printed, rounding the last additional digit. 

1243 

1244 .. versionadded:: 1.21.0 

1245 

1246 Returns 

1247 ------- 

1248 rep : string 

1249 The string representation of the floating point value 

1250 

1251 See Also 

1252 -------- 

1253 format_float_scientific 

1254 

1255 Examples 

1256 -------- 

1257 >>> import numpy as np 

1258 >>> np.format_float_positional(np.float32(np.pi)) 

1259 '3.1415927' 

1260 >>> np.format_float_positional(np.float16(np.pi)) 

1261 '3.14' 

1262 >>> np.format_float_positional(np.float16(0.3)) 

1263 '0.3' 

1264 >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10) 

1265 '0.3000488281' 

1266 """ 

1267 precision = _none_or_positive_arg(precision, 'precision') 

1268 pad_left = _none_or_positive_arg(pad_left, 'pad_left') 

1269 pad_right = _none_or_positive_arg(pad_right, 'pad_right') 

1270 min_digits = _none_or_positive_arg(min_digits, 'min_digits') 

1271 if not fractional and precision == 0: 

1272 raise ValueError("precision must be greater than 0 if " 

1273 "fractional=False") 

1274 if min_digits > 0 and precision > 0 and min_digits > precision: 

1275 raise ValueError("min_digits must be less than or equal to precision") 

1276 return dragon4_positional(x, precision=precision, unique=unique, 

1277 fractional=fractional, trim=trim, 

1278 sign=sign, pad_left=pad_left, 

1279 pad_right=pad_right, min_digits=min_digits) 

1280 

1281class IntegerFormat: 

1282 def __init__(self, data, sign='-'): 

1283 if data.size > 0: 

1284 data_max = np.max(data) 

1285 data_min = np.min(data) 

1286 data_max_str_len = len(str(data_max)) 

1287 if sign == ' ' and data_min < 0: 

1288 sign = '-' 

1289 if data_max >= 0 and sign in "+ ": 

1290 data_max_str_len += 1 

1291 max_str_len = max(data_max_str_len, 

1292 len(str(data_min))) 

1293 else: 

1294 max_str_len = 0 

1295 self.format = f'{{:{sign}{max_str_len}d}}' 

1296 

1297 def __call__(self, x): 

1298 return self.format.format(x) 

1299 

1300class BoolFormat: 

1301 def __init__(self, data, **kwargs): 

1302 # add an extra space so " True" and "False" have the same length and 

1303 # array elements align nicely when printed, except in 0d arrays 

1304 self.truestr = ' True' if data.shape != () else 'True' 

1305 

1306 def __call__(self, x): 

1307 return self.truestr if x else "False" 

1308 

1309 

1310class ComplexFloatingFormat: 

1311 """ Formatter for subtypes of np.complexfloating """ 

1312 def __init__(self, x, precision, floatmode, suppress_small, 

1313 sign=False, *, legacy=None): 

1314 # for backcompatibility, accept bools 

1315 if isinstance(sign, bool): 

1316 sign = '+' if sign else '-' 

1317 

1318 floatmode_real = floatmode_imag = floatmode 

1319 if legacy <= 113: 

1320 floatmode_real = 'maxprec_equal' 

1321 floatmode_imag = 'maxprec' 

1322 

1323 self.real_format = FloatingFormat( 

1324 x.real, precision, floatmode_real, suppress_small, 

1325 sign=sign, legacy=legacy 

1326 ) 

1327 self.imag_format = FloatingFormat( 

1328 x.imag, precision, floatmode_imag, suppress_small, 

1329 sign='+', legacy=legacy 

1330 ) 

1331 

1332 def __call__(self, x): 

1333 r = self.real_format(x.real) 

1334 i = self.imag_format(x.imag) 

1335 

1336 # add the 'j' before the terminal whitespace in i 

1337 sp = len(i.rstrip()) 

1338 i = i[:sp] + 'j' + i[sp:] 

1339 

1340 return r + i 

1341 

1342 

1343class _TimelikeFormat: 

1344 def __init__(self, data): 

1345 non_nat = data[~isnat(data)] 

1346 if len(non_nat) > 0: 

1347 # Max str length of non-NaT elements 

1348 max_str_len = max(len(self._format_non_nat(np.max(non_nat))), 

1349 len(self._format_non_nat(np.min(non_nat)))) 

1350 else: 

1351 max_str_len = 0 

1352 if len(non_nat) < data.size: 

1353 # data contains a NaT 

1354 max_str_len = max(max_str_len, 5) 

1355 self._format = '%{}s'.format(max_str_len) 

1356 self._nat = "'NaT'".rjust(max_str_len) 

1357 

1358 def _format_non_nat(self, x): 

1359 # override in subclass 

1360 raise NotImplementedError 

1361 

1362 def __call__(self, x): 

1363 if isnat(x): 

1364 return self._nat 

1365 else: 

1366 return self._format % self._format_non_nat(x) 

1367 

1368 

1369class DatetimeFormat(_TimelikeFormat): 

1370 def __init__(self, x, unit=None, timezone=None, casting='same_kind', 

1371 legacy=False): 

1372 # Get the unit from the dtype 

1373 if unit is None: 

1374 if x.dtype.kind == 'M': 

1375 unit = datetime_data(x.dtype)[0] 

1376 else: 

1377 unit = 's' 

1378 

1379 if timezone is None: 

1380 timezone = 'naive' 

1381 self.timezone = timezone 

1382 self.unit = unit 

1383 self.casting = casting 

1384 self.legacy = legacy 

1385 

1386 # must be called after the above are configured 

1387 super().__init__(x) 

1388 

1389 def __call__(self, x): 

1390 if self.legacy <= 113: 

1391 return self._format_non_nat(x) 

1392 return super().__call__(x) 

1393 

1394 def _format_non_nat(self, x): 

1395 return "'%s'" % datetime_as_string(x, 

1396 unit=self.unit, 

1397 timezone=self.timezone, 

1398 casting=self.casting) 

1399 

1400 

1401class TimedeltaFormat(_TimelikeFormat): 

1402 def _format_non_nat(self, x): 

1403 return str(x.astype('i8')) 

1404 

1405 

1406class SubArrayFormat: 

1407 def __init__(self, format_function, **options): 

1408 self.format_function = format_function 

1409 self.threshold = options['threshold'] 

1410 self.edge_items = options['edgeitems'] 

1411 

1412 def __call__(self, a): 

1413 self.summary_insert = "..." if a.size > self.threshold else "" 

1414 return self.format_array(a) 

1415 

1416 def format_array(self, a): 

1417 if np.ndim(a) == 0: 

1418 return self.format_function(a) 

1419 

1420 if self.summary_insert and a.shape[0] > 2*self.edge_items: 

1421 formatted = ( 

1422 [self.format_array(a_) for a_ in a[:self.edge_items]] 

1423 + [self.summary_insert] 

1424 + [self.format_array(a_) for a_ in a[-self.edge_items:]] 

1425 ) 

1426 else: 

1427 formatted = [self.format_array(a_) for a_ in a] 

1428 

1429 return "[" + ", ".join(formatted) + "]" 

1430 

1431 

1432class StructuredVoidFormat: 

1433 """ 

1434 Formatter for structured np.void objects. 

1435 

1436 This does not work on structured alias types like 

1437 np.dtype(('i4', 'i2,i2')), as alias scalars lose their field information, 

1438 and the implementation relies upon np.void.__getitem__. 

1439 """ 

1440 def __init__(self, format_functions): 

1441 self.format_functions = format_functions 

1442 

1443 @classmethod 

1444 def from_data(cls, data, **options): 

1445 """ 

1446 This is a second way to initialize StructuredVoidFormat, 

1447 using the raw data as input. Added to avoid changing 

1448 the signature of __init__. 

1449 """ 

1450 format_functions = [] 

1451 for field_name in data.dtype.names: 

1452 format_function = _get_format_function(data[field_name], **options) 

1453 if data.dtype[field_name].shape != (): 

1454 format_function = SubArrayFormat(format_function, **options) 

1455 format_functions.append(format_function) 

1456 return cls(format_functions) 

1457 

1458 def __call__(self, x): 

1459 str_fields = [ 

1460 format_function(field) 

1461 for field, format_function in zip(x, self.format_functions) 

1462 ] 

1463 if len(str_fields) == 1: 

1464 return "({},)".format(str_fields[0]) 

1465 else: 

1466 return "({})".format(", ".join(str_fields)) 

1467 

1468 

1469def _void_scalar_to_string(x, is_repr=True): 

1470 """ 

1471 Implements the repr for structured-void scalars. It is called from the 

1472 scalartypes.c.src code, and is placed here because it uses the elementwise 

1473 formatters defined above. 

1474 """ 

1475 options = format_options.get().copy() 

1476 

1477 if options["legacy"] <= 125: 

1478 return StructuredVoidFormat.from_data(array(x), **options)(x) 

1479 

1480 if options.get('formatter') is None: 

1481 options['formatter'] = {} 

1482 options['formatter'].setdefault('float_kind', str) 

1483 val_repr = StructuredVoidFormat.from_data(array(x), **options)(x) 

1484 if not is_repr: 

1485 return val_repr 

1486 cls = type(x) 

1487 cls_fqn = cls.__module__.replace("numpy", "np") + "." + cls.__name__ 

1488 void_dtype = np.dtype((np.void, x.dtype)) 

1489 return f"{cls_fqn}({val_repr}, dtype={void_dtype!s})" 

1490 

1491 

1492_typelessdata = [int_, float64, complex128, _nt.bool] 

1493 

1494 

1495def dtype_is_implied(dtype): 

1496 """ 

1497 Determine if the given dtype is implied by the representation 

1498 of its values. 

1499 

1500 Parameters 

1501 ---------- 

1502 dtype : dtype 

1503 Data type 

1504 

1505 Returns 

1506 ------- 

1507 implied : bool 

1508 True if the dtype is implied by the representation of its values. 

1509 

1510 Examples 

1511 -------- 

1512 >>> import numpy as np 

1513 >>> np._core.arrayprint.dtype_is_implied(int) 

1514 True 

1515 >>> np.array([1, 2, 3], int) 

1516 array([1, 2, 3]) 

1517 >>> np._core.arrayprint.dtype_is_implied(np.int8) 

1518 False 

1519 >>> np.array([1, 2, 3], np.int8) 

1520 array([1, 2, 3], dtype=int8) 

1521 """ 

1522 dtype = np.dtype(dtype) 

1523 if format_options.get()['legacy'] <= 113 and dtype.type == np.bool: 

1524 return False 

1525 

1526 # not just void types can be structured, and names are not part of the repr 

1527 if dtype.names is not None: 

1528 return False 

1529 

1530 # should care about endianness *unless size is 1* (e.g., int8, bool) 

1531 if not dtype.isnative: 

1532 return False 

1533 

1534 return dtype.type in _typelessdata 

1535 

1536 

1537def dtype_short_repr(dtype): 

1538 """ 

1539 Convert a dtype to a short form which evaluates to the same dtype. 

1540 

1541 The intent is roughly that the following holds 

1542 

1543 >>> from numpy import * 

1544 >>> dt = np.int64([1, 2]).dtype 

1545 >>> assert eval(dtype_short_repr(dt)) == dt 

1546 """ 

1547 if type(dtype).__repr__ != np.dtype.__repr__: 

1548 # TODO: Custom repr for user DTypes, logic should likely move. 

1549 return repr(dtype) 

1550 if dtype.names is not None: 

1551 # structured dtypes give a list or tuple repr 

1552 return str(dtype) 

1553 elif issubclass(dtype.type, flexible): 

1554 # handle these separately so they don't give garbage like str256 

1555 return "'%s'" % str(dtype) 

1556 

1557 typename = dtype.name 

1558 if not dtype.isnative: 

1559 # deal with cases like dtype('<u2') that are identical to an 

1560 # established dtype (in this case uint16) 

1561 # except that they have a different endianness. 

1562 return "'%s'" % str(dtype) 

1563 # quote typenames which can't be represented as python variable names 

1564 if typename and not (typename[0].isalpha() and typename.isalnum()): 

1565 typename = repr(typename) 

1566 return typename 

1567 

1568 

1569def _array_repr_implementation( 

1570 arr, max_line_width=None, precision=None, suppress_small=None, 

1571 array2string=array2string): 

1572 """Internal version of array_repr() that allows overriding array2string.""" 

1573 current_options = format_options.get() 

1574 override_repr = current_options["override_repr"] 

1575 if override_repr is not None: 

1576 return override_repr(arr) 

1577 

1578 if max_line_width is None: 

1579 max_line_width = current_options['linewidth'] 

1580 

1581 if type(arr) is not ndarray: 

1582 class_name = type(arr).__name__ 

1583 else: 

1584 class_name = "array" 

1585 

1586 prefix = class_name + "(" 

1587 if (current_options['legacy'] <= 113 and 

1588 arr.shape == () and not arr.dtype.names): 

1589 lst = repr(arr.item()) 

1590 else: 

1591 lst = array2string(arr, max_line_width, precision, suppress_small, 

1592 ', ', prefix, suffix=")") 

1593 

1594 # Add dtype and shape information if these cannot be inferred from 

1595 # the array string. 

1596 extras = [] 

1597 if (arr.size == 0 and arr.shape != (0,) 

1598 or current_options['legacy'] > 210 

1599 and arr.size > current_options['threshold']): 

1600 extras.append(f"shape={arr.shape}") 

1601 if not dtype_is_implied(arr.dtype) or arr.size == 0: 

1602 extras.append(f"dtype={dtype_short_repr(arr.dtype)}") 

1603 

1604 if not extras: 

1605 return prefix + lst + ")" 

1606 

1607 arr_str = prefix + lst + "," 

1608 extra_str = ", ".join(extras) + ")" 

1609 # compute whether we should put extras on a new line: Do so if adding the 

1610 # extras would extend the last line past max_line_width. 

1611 # Note: This line gives the correct result even when rfind returns -1. 

1612 last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1) 

1613 spacer = " " 

1614 if current_options['legacy'] <= 113: 

1615 if issubclass(arr.dtype.type, flexible): 

1616 spacer = '\n' + ' '*len(prefix) 

1617 elif last_line_len + len(extra_str) + 1 > max_line_width: 

1618 spacer = '\n' + ' '*len(prefix) 

1619 

1620 return arr_str + spacer + extra_str 

1621 

1622 

1623def _array_repr_dispatcher( 

1624 arr, max_line_width=None, precision=None, suppress_small=None): 

1625 return (arr,) 

1626 

1627 

1628@array_function_dispatch(_array_repr_dispatcher, module='numpy') 

1629def array_repr(arr, max_line_width=None, precision=None, suppress_small=None): 

1630 """ 

1631 Return the string representation of an array. 

1632 

1633 Parameters 

1634 ---------- 

1635 arr : ndarray 

1636 Input array. 

1637 max_line_width : int, optional 

1638 Inserts newlines if text is longer than `max_line_width`. 

1639 Defaults to ``numpy.get_printoptions()['linewidth']``. 

1640 precision : int, optional 

1641 Floating point precision. 

1642 Defaults to ``numpy.get_printoptions()['precision']``. 

1643 suppress_small : bool, optional 

1644 Represent numbers "very close" to zero as zero; default is False. 

1645 Very close is defined by precision: if the precision is 8, e.g., 

1646 numbers smaller (in absolute value) than 5e-9 are represented as 

1647 zero. 

1648 Defaults to ``numpy.get_printoptions()['suppress']``. 

1649 

1650 Returns 

1651 ------- 

1652 string : str 

1653 The string representation of an array. 

1654 

1655 See Also 

1656 -------- 

1657 array_str, array2string, set_printoptions 

1658 

1659 Examples 

1660 -------- 

1661 >>> import numpy as np 

1662 >>> np.array_repr(np.array([1,2])) 

1663 'array([1, 2])' 

1664 >>> np.array_repr(np.ma.array([0.])) 

1665 'MaskedArray([0.])' 

1666 >>> np.array_repr(np.array([], np.int32)) 

1667 'array([], dtype=int32)' 

1668 

1669 >>> x = np.array([1e-6, 4e-7, 2, 3]) 

1670 >>> np.array_repr(x, precision=6, suppress_small=True) 

1671 'array([0.000001, 0. , 2. , 3. ])' 

1672 

1673 """ 

1674 return _array_repr_implementation( 

1675 arr, max_line_width, precision, suppress_small) 

1676 

1677 

1678@_recursive_guard() 

1679def _guarded_repr_or_str(v): 

1680 if isinstance(v, bytes): 

1681 return repr(v) 

1682 return str(v) 

1683 

1684 

1685def _array_str_implementation( 

1686 a, max_line_width=None, precision=None, suppress_small=None, 

1687 array2string=array2string): 

1688 """Internal version of array_str() that allows overriding array2string.""" 

1689 if (format_options.get()['legacy'] <= 113 and 

1690 a.shape == () and not a.dtype.names): 

1691 return str(a.item()) 

1692 

1693 # the str of 0d arrays is a special case: It should appear like a scalar, 

1694 # so floats are not truncated by `precision`, and strings are not wrapped 

1695 # in quotes. So we return the str of the scalar value. 

1696 if a.shape == (): 

1697 # obtain a scalar and call str on it, avoiding problems for subclasses 

1698 # for which indexing with () returns a 0d instead of a scalar by using 

1699 # ndarray's getindex. Also guard against recursive 0d object arrays. 

1700 return _guarded_repr_or_str(np.ndarray.__getitem__(a, ())) 

1701 

1702 return array2string(a, max_line_width, precision, suppress_small, ' ', "") 

1703 

1704 

1705def _array_str_dispatcher( 

1706 a, max_line_width=None, precision=None, suppress_small=None): 

1707 return (a,) 

1708 

1709 

1710@array_function_dispatch(_array_str_dispatcher, module='numpy') 

1711def array_str(a, max_line_width=None, precision=None, suppress_small=None): 

1712 """ 

1713 Return a string representation of the data in an array. 

1714 

1715 The data in the array is returned as a single string. This function is 

1716 similar to `array_repr`, the difference being that `array_repr` also 

1717 returns information on the kind of array and its data type. 

1718 

1719 Parameters 

1720 ---------- 

1721 a : ndarray 

1722 Input array. 

1723 max_line_width : int, optional 

1724 Inserts newlines if text is longer than `max_line_width`. 

1725 Defaults to ``numpy.get_printoptions()['linewidth']``. 

1726 precision : int, optional 

1727 Floating point precision. 

1728 Defaults to ``numpy.get_printoptions()['precision']``. 

1729 suppress_small : bool, optional 

1730 Represent numbers "very close" to zero as zero; default is False. 

1731 Very close is defined by precision: if the precision is 8, e.g., 

1732 numbers smaller (in absolute value) than 5e-9 are represented as 

1733 zero. 

1734 Defaults to ``numpy.get_printoptions()['suppress']``. 

1735 

1736 See Also 

1737 -------- 

1738 array2string, array_repr, set_printoptions 

1739 

1740 Examples 

1741 -------- 

1742 >>> import numpy as np 

1743 >>> np.array_str(np.arange(3)) 

1744 '[0 1 2]' 

1745 

1746 """ 

1747 return _array_str_implementation( 

1748 a, max_line_width, precision, suppress_small) 

1749 

1750 

1751# needed if __array_function__ is disabled 

1752_array2string_impl = getattr(array2string, '__wrapped__', array2string) 

1753_default_array_str = functools.partial(_array_str_implementation, 

1754 array2string=_array2string_impl) 

1755_default_array_repr = functools.partial(_array_repr_implementation, 

1756 array2string=_array2string_impl)