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", "set_string_function",

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

25 import functools

26 import numbers

27 import sys

28 try:

29 from _thread import get_ident

30 except ImportError:

31 from _dummy_thread import get_ident

32

33 import numpy as np

34 from . import numerictypes as _nt

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

36 from . import multiarray

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

38 datetime_as_string, datetime_data, ndarray,

39 set_legacy_print_mode)

40 from .fromnumeric import any

41 from .numeric import concatenate, asarray, errstate

42 from .numerictypes import (longlong, intc, int_, float_, complex_, bool_,

43 flexible)

44 from .overrides import array_function_dispatch, set_module

45 import operator

46 import warnings

47 import contextlib

48

49_format_options = {

50 'edgeitems': 3, # repr N leading and trailing items of each dimension

51 'threshold': 1000, # total items > triggers array summarization

52 'floatmode': 'maxprec',

53 'precision': 8, # precision of floating point representations

54 'suppress': False, # suppress printing small floating values in exp format

55 'linewidth': 75,

56 'nanstr': 'nan',

57 'infstr': 'inf',

58 'sign': '-',

59 'formatter': None,

60 # Internally stored as an int to simplify comparisons; converted from/to

61 # str/False on the way in/out.

62 'legacy': sys.maxsize}

63

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

65 linewidth=None, suppress=None, nanstr=None, infstr=None,

66 sign=None, formatter=None, floatmode=None, legacy=None):

67 """

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

69 *legacy* and sanity checks.

70 """

71

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

73

74 if suppress is not None:

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

76

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

78 if floatmode not in modes + [None]:

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

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

81

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

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

84

85 if legacy == False:

86 options['legacy'] = sys.maxsize

87 elif legacy == '1.13':

88 options['legacy'] = 113

89 elif legacy == '1.21':

90 options['legacy'] = 121

91 elif legacy is None:

92 pass # OK, do nothing.

93 else:

94 warnings.warn(

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

96 "`False`", stacklevel=3)

97

98 if threshold is not None:

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

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

101 raise TypeError("threshold must be numeric")

102 if np.isnan(threshold):

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

104 "sys.maxsize for untruncated representation")

105

106 if precision is not None:

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

108 try:

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

110 except TypeError as e:

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

112

113 return options

114

115

116@set_module('numpy')

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

118 linewidth=None, suppress=None, nanstr=None, infstr=None,

119 formatter=None, sign=None, floatmode=None, *, legacy=None):

120 """

121 Set printing options.

122

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

124 other NumPy objects are displayed.

125

126 Parameters

127 ----------

128 precision : int or None, optional

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

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

131 necessary to uniquely specify the value.

132 threshold : int, optional

133 Total number of array elements which trigger summarization

134 rather than full repr (default 1000).

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

136 edgeitems : int, optional

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

138 each dimension (default 3).

139 linewidth : int, optional

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

141 line breaks (default 75).

142 suppress : bool, optional

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

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

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

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

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

148 nanstr : str, optional

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

150 infstr : str, optional

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

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

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

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

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

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

157 formatter : dict of callables, optional

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

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

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

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

162 can be set are:

163

164 - 'bool'

165 - 'int'

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

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

168 - 'float'

169 - 'longfloat' : 128-bit floats

170 - 'complexfloat'

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

172 - 'numpystr' : types `numpy.string_` and `numpy.unicode_`

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

174

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

176

177 - 'all' : sets all types

178 - 'int_kind' : sets 'int'

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

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

181 - 'str_kind' : sets 'numpystr'

182 floatmode : str, optional

183 Controls the interpretation of the `precision` option for

184 floating-point types. Can take the following values

185 (default maxprec_equal):

186

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

188 even if this would print more or fewer digits than

189 necessary to specify the value uniquely.

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

191 to represent each value uniquely. Different elements may

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

193 `precision` option is ignored.

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

195 an element can be uniquely represented with fewer digits

196 only print it with that many.

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

198 but if every element in the array can be uniquely

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

200 many digits for all elements.

201 legacy : string or `False`, optional

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

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

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

205 enables 1.21 legacy printing mode (described below).

206

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

208 approximates numpy 1.21 print output of complex structured dtypes

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

210 colons.

211

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

213

214 Unrecognized strings will be ignored with a warning for forward

215 compatibility.

216

217 .. versionadded:: 1.14.0

218 .. versionchanged:: 1.22.0

219

220 See Also

221 --------

222 get_printoptions, printoptions, set_string_function, array2string

223

224 Notes

225 -----

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

227

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

229

230 Examples

231 --------

232 Floating point precision can be set:

233

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

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

236 [1.1235]

237

238 Long arrays can be summarised:

239

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

241 >>> np.arange(10)

242 array([0, 1, 2, ..., 7, 8, 9])

243

244 Small results can be suppressed:

245

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

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

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

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

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

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

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

253

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

255

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

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

258 >>> x

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

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

261 >>> x

262 array([0, 1, 2])

263

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

265

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

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

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

269

270 Also to temporarily override options, use `printoptions` as a context manager:

271

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

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

274 array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ])

275

276 """

277 opt = _make_options_dict(precision, threshold, edgeitems, linewidth,

278 suppress, nanstr, infstr, sign, formatter,

279 floatmode, legacy)

280 # formatter is always reset

281 opt['formatter'] = formatter

282 _format_options.update(opt)

283

284 # set the C variable for legacy mode

285 if _format_options['legacy'] == 113:

286 set_legacy_print_mode(113)

287 # reset the sign option in legacy mode to avoid confusion

288 _format_options['sign'] = '-'

289 elif _format_options['legacy'] == 121:

290 set_legacy_print_mode(121)

291 elif _format_options['legacy'] == sys.maxsize:

292 set_legacy_print_mode(0)

293

294

295@set_module('numpy')

296 def get_printoptions():

297 """

298 Return the current print options.

299

300 Returns

301 -------

302 print_opts : dict

303 Dictionary of current print options with keys

304

305 - precision : int

306 - threshold : int

307 - edgeitems : int

308 - linewidth : int

309 - suppress : bool

310 - nanstr : str

311 - infstr : str

312 - formatter : dict of callables

313 - sign : str

314

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

316

317 See Also

318 --------

319 set_printoptions, printoptions, set_string_function

320

321 """

322 opts = _format_options.copy()

323 opts['legacy'] = {

324 113: '1.13', 121: '1.21', sys.maxsize: False,

325 }[opts['legacy']]

326 return opts

327

328

329 def _get_legacy_print_mode():

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

331 return _format_options['legacy']

332

333

334@set_module('numpy')

335@contextlib.contextmanager

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

337 """Context manager for setting print options.

338

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

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

341 available options.

342

343 Examples

344 --------

345

346 >>> from numpy.testing import assert_equal

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

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

349 array([0.67])

350

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

352

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

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

355

356 See Also

357 --------

358 set_printoptions, get_printoptions

359

360 """

361 opts = np.get_printoptions()

362 try:

363 np.set_printoptions(*args, **kwargs)

364 yield np.get_printoptions()

365 finally:

366 np.set_printoptions(**opts)

367

368

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

370 """

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

372

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

374 preserving subclasses.

375 """

376 axis = len(index)

377 if axis == a.ndim:

378 return a[index]

379

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

381 return concatenate((

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

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

384 ), axis=axis)

385 else:

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

387

388

389 def _object_format(o):

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

391 if type(o) is list:

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

393 else:

394 fmt = '{!r}'

395 return fmt.format(o)

396

397 def repr_format(x):

398 return repr(x)

399

400 def str_format(x):

401 return str(x)

402

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

404 formatter, **kwargs):

405 # note: extra arguments in kwargs are ignored

406

407 # wrapped in lambdas to avoid taking a code path with the wrong type of data

408 formatdict = {

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

410 'int': lambda: IntegerFormat(data),

411 'float': lambda: FloatingFormat(

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

413 'longfloat': lambda: FloatingFormat(

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

415 'complexfloat': lambda: ComplexFloatingFormat(

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

417 'longcomplexfloat': lambda: ComplexFloatingFormat(

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

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

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

421 'object': lambda: _object_format,

422 'void': lambda: str_format,

423 'numpystr': lambda: repr_format}

424

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

426 # is the same as the above values.

427 def indirect(x):

428 return lambda: x

429

430 if formatter is not None:

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

432 if 'all' in fkeys:

433 for key in formatdict.keys():

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

435 if 'int_kind' in fkeys:

436 for key in ['int']:

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

438 if 'float_kind' in fkeys:

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

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

441 if 'complex_kind' in fkeys:

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

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

444 if 'str_kind' in fkeys:

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

446 for key in formatdict.keys():

447 if key in fkeys:

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

449

450 return formatdict

451

452 def _get_format_function(data, **options):

453 """

454 find the right formatting function for the dtype_

455 """

456 dtype_ = data.dtype

457 dtypeobj = dtype_.type

458 formatdict = _get_formatdict(data, **options)

459 if dtypeobj is None:

460 return formatdict["numpystr"]()

461 elif issubclass(dtypeobj, _nt.bool_):

462 return formatdict['bool']()

463 elif issubclass(dtypeobj, _nt.integer):

464 if issubclass(dtypeobj, _nt.timedelta64):

465 return formatdict['timedelta']()

466 else:

467 return formatdict['int']()

468 elif issubclass(dtypeobj, _nt.floating):

469 if issubclass(dtypeobj, _nt.longfloat):

470 return formatdict['longfloat']()

471 else:

472 return formatdict['float']()

473 elif issubclass(dtypeobj, _nt.complexfloating):

474 if issubclass(dtypeobj, _nt.clongfloat):

475 return formatdict['longcomplexfloat']()

476 else:

477 return formatdict['complexfloat']()

478 elif issubclass(dtypeobj, (_nt.unicode_, _nt.string_)):

479 return formatdict['numpystr']()

480 elif issubclass(dtypeobj, _nt.datetime64):

481 return formatdict['datetime']()

482 elif issubclass(dtypeobj, _nt.object_):

483 return formatdict['object']()

484 elif issubclass(dtypeobj, _nt.void):

485 if dtype_.names is not None:

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

487 else:

488 return formatdict['void']()

489 else:

490 return formatdict['numpystr']()

491

492

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

494 """

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

496

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

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

499

500 Largely copied from reprlib.recursive_repr

501 """

502

503 def decorating_function(f):

504 repr_running = set()

505

506 @functools.wraps(f)

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

508 key = id(self), get_ident()

509 if key in repr_running:

510 return fillvalue

511 repr_running.add(key)

512 try:

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

514 finally:

515 repr_running.discard(key)

516

517 return wrapper

518

519 return decorating_function

520

521

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

523@_recursive_guard()

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

525 # The formatter __init__s in _get_format_function cannot deal with

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

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

528 data = asarray(a)

529 if a.shape == ():

530 a = data

531

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

533 summary_insert = "..."

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

535 else:

536 summary_insert = ""

537

538 # find the right formatting function for the array

539 format_function = _get_format_function(data, **options)

540

541 # skip over "["

542 next_line_prefix = " "

543 # skip over array(

544 next_line_prefix += " "*len(prefix)

545

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

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

548 summary_insert, options['legacy'])

549 return lst

550

551

552 def _array2string_dispatcher(

553 a, max_line_width=None, precision=None,

554 suppress_small=None, separator=None, prefix=None,

555 style=None, formatter=None, threshold=None,

556 edgeitems=None, sign=None, floatmode=None, suffix=None,

557 *, legacy=None):

558 return (a,)

559

560

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

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

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

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

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

566 *, legacy=None):

567 """

568 Return a string representation of an array.

569

570 Parameters

571 ----------

572 a : ndarray

573 Input array.

574 max_line_width : int, optional

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

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

577 precision : int or None, optional

578 Floating point precision.

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

580 suppress_small : bool, optional

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

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

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

584 zero.

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

586 separator : str, optional

587 Inserted between elements.

588 prefix : str, optional

589 suffix : str, optional

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

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

592

593 prefix + array2string(a) + suffix

594

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

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

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

598 not included in the output.

599 style : _NoValue, optional

600 Has no effect, do not use.

601

602 .. deprecated:: 1.14.0

603 formatter : dict of callables, optional

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

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

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

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

608 can be set are:

609

610 - 'bool'

611 - 'int'

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

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

614 - 'float'

615 - 'longfloat' : 128-bit floats

616 - 'complexfloat'

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

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

619 - 'numpystr' : types `numpy.string_` and `numpy.unicode_`

620

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

622

623 - 'all' : sets all types

624 - 'int_kind' : sets 'int'

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

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

627 - 'str_kind' : sets 'numpystr'

628 threshold : int, optional

629 Total number of array elements which trigger summarization

630 rather than full repr.

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

632 edgeitems : int, optional

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

634 each dimension.

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

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

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

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

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

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

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

642 floatmode : str, optional

643 Controls the interpretation of the `precision` option for

644 floating-point types.

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

646 Can take the following values:

647

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

649 even if this would print more or fewer digits than

650 necessary to specify the value uniquely.

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

652 to represent each value uniquely. Different elements may

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

654 `precision` option is ignored.

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

656 an element can be uniquely represented with fewer digits

657 only print it with that many.

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

659 but if every element in the array can be uniquely

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

661 many digits for all elements.

662 legacy : string or `False`, optional

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

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

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

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

667 with a warning for forward compatibility.

668

669 .. versionadded:: 1.14.0

670

671 Returns

672 -------

673 array_str : str

674 String representation of the array.

675

676 Raises

677 ------

678 TypeError

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

680

681 See Also

682 --------

683 array_str, array_repr, set_printoptions, get_printoptions

684

685 Notes

686 -----

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

688 ignored for that type.

689

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

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

692 identically in all three functions.

693

694 Examples

695 --------

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

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

698 ... suppress_small=True)

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

700

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

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

703 '[0.00 1.00 2.00]'

704

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

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

707 '[0x0 0x1 0x2]'

708

709 """

710

711 overrides = _make_options_dict(precision, threshold, edgeitems,

712 max_line_width, suppress_small, None, None,

713 sign, formatter, floatmode, legacy)

714 options = _format_options.copy()

715 options.update(overrides)

716

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

718 if style is np._NoValue:

719 style = repr

720

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

722 return style(a.item())

723 elif style is not np._NoValue:

724 # Deprecation 11-9-2017 v1.14

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

726 " except in 1.13 'legacy' mode",

727 DeprecationWarning, stacklevel=3)

728

729 if options['legacy'] > 113:

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

731

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

733 if a.size == 0:

734 return "[]"

735

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

737

738

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

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

741 if legacy > 113:

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

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

744 needs_wrap = False

745

746 if needs_wrap:

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

748 line = next_line_prefix

749 line += word

750 return s, line

751

752

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

754 """

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

756 """

757 words = word.splitlines()

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

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

760

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

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

763 len(line) > len(next_line_prefix)):

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

765 line = next_line_prefix + words[0]

766 indent = next_line_prefix

767 else:

768 indent = len(line)*' '

769 line += words[0]

770

771 for word in words[1::]:

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

773 line = indent + word

774

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

776 line += suffix_length*' '

777

778 return s, line

779

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

781 separator, edge_items, summary_insert, legacy):

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

783

784 1. Full output

785

786 2. Summarized output

787

788 """

789 def recurser(index, hanging_indent, curr_width):

790 """

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

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

793 not significant

794 """

795 axis = len(index)

796 axes_left = a.ndim - axis

797

798 if axes_left == 0:

799 return format_function(a[index])

800

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

802 # length of the line by 1

803 next_hanging_indent = hanging_indent + ' '

804 if legacy <= 113:

805 next_width = curr_width

806 else:

807 next_width = curr_width - len(']')

808

809 a_len = a.shape[axis]

810 show_summary = summary_insert and 2*edge_items < a_len

811 if show_summary:

812 leading_items = edge_items

813 trailing_items = edge_items

814 else:

815 leading_items = 0

816 trailing_items = a_len

817

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

819 s = ''

820

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

822 if axes_left == 1:

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

824 if legacy <= 113:

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

826 else:

827 elem_width = curr_width - max(len(separator.rstrip()), len(']'))

828

829 line = hanging_indent

830 for i in range(leading_items):

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

832 s, line = _extendLine_pretty(

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

834 line += separator

835

836 if show_summary:

837 s, line = _extendLine(

838 s, line, summary_insert, elem_width, hanging_indent, legacy)

839 if legacy <= 113:

840 line += ", "

841 else:

842 line += separator

843

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

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

846 s, line = _extendLine_pretty(

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

848 line += separator

849

850 if legacy <= 113:

851 # width of the separator is not considered on 1.13

852 elem_width = curr_width

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

854 s, line = _extendLine_pretty(

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

856

857 s += line

858

859 # other axes - insert newlines between rows

860 else:

861 s = ''

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

863

864 for i in range(leading_items):

865 nested = recurser(index + (i,), next_hanging_indent, next_width)

866 s += hanging_indent + nested + line_sep

867

868 if show_summary:

869 if legacy <= 113:

870 # trailing space, fixed nbr of newlines, and fixed separator

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

872 else:

873 s += hanging_indent + summary_insert + line_sep

874

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

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

877 next_width)

878 s += hanging_indent + nested + line_sep

879

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

881 s += hanging_indent + nested

882

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

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

885 return s

886

887 try:

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

889 return recurser(index=(),

890 hanging_indent=next_line_prefix,

891 curr_width=line_width)

892 finally:

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

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

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

896 recurser = None

897

898 def _none_or_positive_arg(x, name):

899 if x is None:

900 return -1

901 if x < 0:

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

903 return x

904

905 class FloatingFormat:

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

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

908 *, legacy=None):

909 # for backcompatibility, accept bools

910 if isinstance(sign, bool):

911 sign = '+' if sign else '-'

912

913 self._legacy = legacy

914 if self._legacy <= 113:

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

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

917 sign = ' '

918

919 self.floatmode = floatmode

920 if floatmode == 'unique':

921 self.precision = None

922 else:

923 self.precision = precision

924

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

926

927 self.suppress_small = suppress_small

928 self.sign = sign

929 self.exp_format = False

930 self.large_exponent = False

931

932 self.fillFormat(data)

933

934 def fillFormat(self, data):

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

936 finite_vals = data[isfinite(data)]

937

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

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

940 if len(abs_non_zero) != 0:

941 max_val = np.max(abs_non_zero)

942 min_val = np.min(abs_non_zero)

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

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

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

946 self.exp_format = True

947

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

949 if len(finite_vals) == 0:

950 self.pad_left = 0

951 self.pad_right = 0

952 self.trim = '.'

953 self.exp_size = -1

954 self.unique = True

955 self.min_digits = None

956 elif self.exp_format:

957 trim, unique = '.', True

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

959 trim, unique = 'k', False

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

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

962 for x in finite_vals)

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

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

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

966

967 self.trim = 'k'

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

969 self.min_digits = self.precision

970 self.unique = unique

971

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

973 if self._legacy <= 113:

974 self.pad_left = 3

975 else:

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

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

978 # pad_right is only needed for nan length calculation

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

980 else:

981 trim, unique = '.', True

982 if self.floatmode == 'fixed':

983 trim, unique = 'k', False

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

985 fractional=True,

986 unique=unique, trim=trim,

987 sign=self.sign == '+')

988 for x in finite_vals)

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

990 if self._legacy <= 113:

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

992 else:

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

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

995 self.exp_size = -1

996 self.unique = unique

997

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

999 self.precision = self.min_digits = self.pad_right

1000 self.trim = 'k'

1001 else:

1002 self.trim = '.'

1003 self.min_digits = 0

1004

1005 if self._legacy > 113:

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

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

1008 self.pad_left += 1

1009

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

1011 if data.size != finite_vals.size:

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

1013 nanlen = len(_format_options['nanstr'])

1014 inflen = len(_format_options['infstr']) + neginf

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

1016 self.pad_left = max(self.pad_left, nanlen - offset, inflen - offset)

1017

1018 def __call__(self, x):

1019 if not np.isfinite(x):

1020 with errstate(invalid='ignore'):

1021 if np.isnan(x):

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

1023 ret = sign + _format_options['nanstr']

1024 else: # isinf

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

1026 ret = sign + _format_options['infstr']

1027 return ' '*(self.pad_left + self.pad_right + 1 - len(ret)) + ret

1028

1029 if self.exp_format:

1030 return dragon4_scientific(x,

1031 precision=self.precision,

1032 min_digits=self.min_digits,

1033 unique=self.unique,

1034 trim=self.trim,

1035 sign=self.sign == '+',

1036 pad_left=self.pad_left,

1037 exp_digits=self.exp_size)

1038 else:

1039 return dragon4_positional(x,

1040 precision=self.precision,

1041 min_digits=self.min_digits,

1042 unique=self.unique,

1043 fractional=True,

1044 trim=self.trim,

1045 sign=self.sign == '+',

1046 pad_left=self.pad_left,

1047 pad_right=self.pad_right)

1048

1049

1050@set_module('numpy')

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

1052 sign=False, pad_left=None, exp_digits=None,

1053 min_digits=None):

1054 """

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

1056

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

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

1059

1060 Parameters

1061 ----------

1062 x : python float or numpy floating scalar

1063 Value to format.

1064 precision : non-negative integer or None, optional

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

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

1067 unique : boolean, optional

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

1069 representation which uniquely identifies the floating-point number from

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

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

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

1073 with unbiased rounding.

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

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

1076 value with unbiased rounding

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

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

1079

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

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

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

1083 zero if it is missing.

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

1085 sign : boolean, optional

1086 Whether to show the sign for positive values.

1087 pad_left : non-negative integer, optional

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

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

1090 exp_digits : non-negative integer, optional

1091 Pad the exponent with zeros until it contains at least this many digits.

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

1093 min_digits : non-negative integer or None, optional

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

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

1096 identify the value may be printed and rounded unbiased.

1097

1098 -- versionadded:: 1.21.0

1099

1100 Returns

1101 -------

1102 rep : string

1103 The string representation of the floating point value

1104

1105 See Also

1106 --------

1107 format_float_positional

1108

1109 Examples

1110 --------

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

1112 '3.1415927e+00'

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

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

1115 '1.230000071797338e+24'

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

1117 '1.23e+0024'

1118 """

1119 precision = _none_or_positive_arg(precision, 'precision')

1120 pad_left = _none_or_positive_arg(pad_left, 'pad_left')

1121 exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits')

1122 min_digits = _none_or_positive_arg(min_digits, 'min_digits')

1123 if min_digits > 0 and precision > 0 and min_digits > precision:

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

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

1126 trim=trim, sign=sign, pad_left=pad_left,

1127 exp_digits=exp_digits, min_digits=min_digits)

1128

1129

1130@set_module('numpy')

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

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

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

1134 """

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

1136

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

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

1139

1140 Parameters

1141 ----------

1142 x : python float or numpy floating scalar

1143 Value to format.

1144 precision : non-negative integer or None, optional

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

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

1147 unique : boolean, optional

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

1149 representation which uniquely identifies the floating-point number from

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

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

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

1153 with unbiased rounding.

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

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

1156 value with unbiased rounding

1157 fractional : boolean, optional

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

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

1160 zeros.

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

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

1163 zeros.

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

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

1166

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

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

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

1170 zero if it is missing.

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

1172 sign : boolean, optional

1173 Whether to show the sign for positive values.

1174 pad_left : non-negative integer, optional

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

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

1177 pad_right : non-negative integer, optional

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

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

1180 min_digits : non-negative integer or None, optional

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

1182 in which case additional digits past those necessary to uniquely

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

1184

1185 -- versionadded:: 1.21.0

1186

1187 Returns

1188 -------

1189 rep : string

1190 The string representation of the floating point value

1191

1192 See Also

1193 --------

1194 format_float_scientific

1195

1196 Examples

1197 --------

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

1199 '3.1415927'

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

1201 '3.14'

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

1203 '0.3'

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

1205 '0.3000488281'

1206 """

1207 precision = _none_or_positive_arg(precision, 'precision')

1208 pad_left = _none_or_positive_arg(pad_left, 'pad_left')

1209 pad_right = _none_or_positive_arg(pad_right, 'pad_right')

1210 min_digits = _none_or_positive_arg(min_digits, 'min_digits')

1211 if not fractional and precision == 0:

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

1213 "fractional=False")

1214 if min_digits > 0 and precision > 0 and min_digits > precision:

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

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

1217 fractional=fractional, trim=trim,

1218 sign=sign, pad_left=pad_left,

1219 pad_right=pad_right, min_digits=min_digits)

1220

1221

1222 class IntegerFormat:

1223 def __init__(self, data):

1224 if data.size > 0:

1225 max_str_len = max(len(str(np.max(data))),

1226 len(str(np.min(data))))

1227 else:

1228 max_str_len = 0

1229 self.format = '%{}d'.format(max_str_len)

1230

1231 def __call__(self, x):

1232 return self.format % x

1233

1234

1235 class BoolFormat:

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

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

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

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

1240

1241 def __call__(self, x):

1242 return self.truestr if x else "False"

1243

1244

1245 class ComplexFloatingFormat:

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

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

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

1249 # for backcompatibility, accept bools

1250 if isinstance(sign, bool):

1251 sign = '+' if sign else '-'

1252

1253 floatmode_real = floatmode_imag = floatmode

1254 if legacy <= 113:

1255 floatmode_real = 'maxprec_equal'

1256 floatmode_imag = 'maxprec'

1257

1258 self.real_format = FloatingFormat(

1259 x.real, precision, floatmode_real, suppress_small,

1260 sign=sign, legacy=legacy

1261 )

1262 self.imag_format = FloatingFormat(

1263 x.imag, precision, floatmode_imag, suppress_small,

1264 sign='+', legacy=legacy

1265 )

1266

1267 def __call__(self, x):

1268 r = self.real_format(x.real)

1269 i = self.imag_format(x.imag)

1270

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

1272 sp = len(i.rstrip())

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

1274

1275 return r + i

1276

1277

1278 class _TimelikeFormat:

1279 def __init__(self, data):

1280 non_nat = data[~isnat(data)]

1281 if len(non_nat) > 0:

1282 # Max str length of non-NaT elements

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

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

1285 else:

1286 max_str_len = 0

1287 if len(non_nat) < data.size:

1288 # data contains a NaT

1289 max_str_len = max(max_str_len, 5)

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

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

1292

1293 def _format_non_nat(self, x):

1294 # override in subclass

1295 raise NotImplementedError

1296

1297 def __call__(self, x):

1298 if isnat(x):

1299 return self._nat

1300 else:

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

1302

1303

1304 class DatetimeFormat(_TimelikeFormat):

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

1306 legacy=False):

1307 # Get the unit from the dtype

1308 if unit is None:

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

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

1311 else:

1312 unit = 's'

1313

1314 if timezone is None:

1315 timezone = 'naive'

1316 self.timezone = timezone

1317 self.unit = unit

1318 self.casting = casting

1319 self.legacy = legacy

1320

1321 # must be called after the above are configured

1322 super().__init__(x)

1323

1324 def __call__(self, x):

1325 if self.legacy <= 113:

1326 return self._format_non_nat(x)

1327 return super().__call__(x)

1328

1329 def _format_non_nat(self, x):

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

1331 unit=self.unit,

1332 timezone=self.timezone,

1333 casting=self.casting)

1334

1335

1336 class TimedeltaFormat(_TimelikeFormat):

1337 def _format_non_nat(self, x):

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

1339

1340

1341 class SubArrayFormat:

1342 def __init__(self, format_function):

1343 self.format_function = format_function

1344

1345 def __call__(self, arr):

1346 if arr.ndim <= 1:

1347 return "[" + ", ".join(self.format_function(a) for a in arr) + "]"

1348 return "[" + ", ".join(self.__call__(a) for a in arr) + "]"

1349

1350

1351 class StructuredVoidFormat:

1352 """

1353 Formatter for structured np.void objects.

1354

1355 This does not work on structured alias types like np.dtype(('i4', 'i2,i2')),

1356 as alias scalars lose their field information, and the implementation

1357 relies upon np.void.__getitem__.

1358 """

1359 def __init__(self, format_functions):

1360 self.format_functions = format_functions

1361

1362 @classmethod

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

1364 """

1365 This is a second way to initialize StructuredVoidFormat, using the raw data

1366 as input. Added to avoid changing the signature of __init__.

1367 """

1368 format_functions = []

1369 for field_name in data.dtype.names:

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

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

1372 format_function = SubArrayFormat(format_function)

1373 format_functions.append(format_function)

1374 return cls(format_functions)

1375

1376 def __call__(self, x):

1377 str_fields = [

1378 format_function(field)

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

1380 ]

1381 if len(str_fields) == 1:

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

1383 else:

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

1385

1386

1387 def _void_scalar_repr(x):

1388 """

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

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

1391 formatters defined above.

1392 """

1393 return StructuredVoidFormat.from_data(array(x), **_format_options)(x)

1394

1395

1396_typelessdata = [int_, float_, complex_, bool_]

1397

1398

1399 def dtype_is_implied(dtype):

1400 """

1401 Determine if the given dtype is implied by the representation of its values.

1402

1403 Parameters

1404 ----------

1405 dtype : dtype

1406 Data type

1407

1408 Returns

1409 -------

1410 implied : bool

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

1412

1413 Examples

1414 --------

1415 >>> np.core.arrayprint.dtype_is_implied(int)

1416 True

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

1418 array([1, 2, 3])

1419 >>> np.core.arrayprint.dtype_is_implied(np.int8)

1420 False

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

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

1423 """

1424 dtype = np.dtype(dtype)

1425 if _format_options['legacy'] <= 113 and dtype.type == bool_:

1426 return False

1427

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

1429 if dtype.names is not None:

1430 return False

1431

1432 return dtype.type in _typelessdata

1433

1434

1435 def dtype_short_repr(dtype):

1436 """

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

1438

1439 The intent is roughly that the following holds

1440

1441 >>> from numpy import *

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

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

1444 """

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

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

1447 return repr(dtype)

1448 if dtype.names is not None:

1449 # structured dtypes give a list or tuple repr

1450 return str(dtype)

1451 elif issubclass(dtype.type, flexible):

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

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

1454

1455 typename = dtype.name

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

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

1458 typename = repr(typename)

1459

1460 return typename

1461

1462

1463 def _array_repr_implementation(

1464 arr, max_line_width=None, precision=None, suppress_small=None,

1465 array2string=array2string):

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

1467 if max_line_width is None:

1468 max_line_width = _format_options['linewidth']

1469

1470 if type(arr) is not ndarray:

1471 class_name = type(arr).__name__

1472 else:

1473 class_name = "array"

1474

1475 skipdtype = dtype_is_implied(arr.dtype) and arr.size > 0

1476

1477 prefix = class_name + "("

1478 suffix = ")" if skipdtype else ","

1479

1480 if (_format_options['legacy'] <= 113 and

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

1482 lst = repr(arr.item())

1483 elif arr.size > 0 or arr.shape == (0,):

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

1485 ', ', prefix, suffix=suffix)

1486 else: # show zero-length shape unless it is (0,)

1487 lst = "[], shape=%s" % (repr(arr.shape),)

1488

1489 arr_str = prefix + lst + suffix

1490

1491 if skipdtype:

1492 return arr_str

1493

1494 dtype_str = "dtype={})".format(dtype_short_repr(arr.dtype))

1495

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

1497 # dtype would extend the last line past max_line_width.

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

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

1500 spacer = " "

1501 if _format_options['legacy'] <= 113:

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

1503 spacer = '\n' + ' '*len(class_name + "(")

1504 elif last_line_len + len(dtype_str) + 1 > max_line_width:

1505 spacer = '\n' + ' '*len(class_name + "(")

1506

1507 return arr_str + spacer + dtype_str

1508

1509

1510 def _array_repr_dispatcher(

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

1512 return (arr,)

1513

1514

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

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

1517 """

1518 Return the string representation of an array.

1519

1520 Parameters

1521 ----------

1522 arr : ndarray

1523 Input array.

1524 max_line_width : int, optional

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

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

1527 precision : int, optional

1528 Floating point precision.

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

1530 suppress_small : bool, optional

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

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

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

1534 zero.

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

1536

1537 Returns

1538 -------

1539 string : str

1540 The string representation of an array.

1541

1542 See Also

1543 --------

1544 array_str, array2string, set_printoptions

1545

1546 Examples

1547 --------

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

1549 'array([1, 2])'

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

1551 'MaskedArray([0.])'

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

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

1554

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

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

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

1558

1559 """

1560 return _array_repr_implementation(

1561 arr, max_line_width, precision, suppress_small)

1562

1563

1564@_recursive_guard()

1565 def _guarded_repr_or_str(v):

1566 if isinstance(v, bytes):

1567 return repr(v)

1568 return str(v)

1569

1570

1571 def _array_str_implementation(

1572 a, max_line_width=None, precision=None, suppress_small=None,

1573 array2string=array2string):

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

1575 if (_format_options['legacy'] <= 113 and

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

1577 return str(a.item())

1578

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

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

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

1582 if a.shape == ():

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

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

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

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

1587

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

1589

1590

1591 def _array_str_dispatcher(

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

1593 return (a,)

1594

1595

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

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

1598 """

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

1600

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

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

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

1604

1605 Parameters

1606 ----------

1607 a : ndarray

1608 Input array.

1609 max_line_width : int, optional

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

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

1612 precision : int, optional

1613 Floating point precision.

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

1615 suppress_small : bool, optional

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

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

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

1619 zero.

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

1621

1622 See Also

1623 --------

1624 array2string, array_repr, set_printoptions

1625

1626 Examples

1627 --------

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

1629 '[0 1 2]'

1630

1631 """

1632 return _array_str_implementation(

1633 a, max_line_width, precision, suppress_small)

1634

1635

1636# needed if __array_function__ is disabled

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

1638_default_array_str = functools.partial(_array_str_implementation,

1639 array2string=_array2string_impl)

1640_default_array_repr = functools.partial(_array_repr_implementation,

1641 array2string=_array2string_impl)

1642

1643

1644 def set_string_function(f, repr=True):

1645 """

1646 Set a Python function to be used when pretty printing arrays.

1647

1648 Parameters

1649 ----------

1650 f : function or None

1651 Function to be used to pretty print arrays. The function should expect

1652 a single array argument and return a string of the representation of

1653 the array. If None, the function is reset to the default NumPy function

1654 to print arrays.

1655 repr : bool, optional

1656 If True (default), the function for pretty printing (``__repr__``)

1657 is set, if False the function that returns the default string

1658 representation (``__str__``) is set.

1659

1660 See Also

1661 --------

1662 set_printoptions, get_printoptions

1663

1664 Examples

1665 --------

1666 >>> def pprint(arr):

1667 ... return 'HA! - What are you going to do now?'

1668 ...

1669 >>> np.set_string_function(pprint)

1670 >>> a = np.arange(10)

1671 >>> a

1672 HA! - What are you going to do now?

1673 >>> _ = a

1674 >>> # [0 1 2 3 4 5 6 7 8 9]

1675

1676 We can reset the function to the default:

1677

1678 >>> np.set_string_function(None)

1679 >>> a

1680 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

1681

1682 `repr` affects either pretty printing or normal string representation.

1683 Note that ``__repr__`` is still affected by setting ``__str__``

1684 because the width of each array element in the returned string becomes

1685 equal to the length of the result of ``__str__()``.

1686

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

1688 >>> np.set_string_function(lambda x:'random', repr=False)

1689 >>> x.__str__()

1690 'random'

1691 >>> x.__repr__()

1692 'array([0, 1, 2, 3])'

1693

1694 """

1695 if f is None:

1696 if repr:

1697 return multiarray.set_string_function(_default_array_repr, 1)

1698 else:

1699 return multiarray.set_string_function(_default_array_str, 0)

1700 else:

1701 return multiarray.set_string_function(f, repr)