arrayprint.py 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756
  1. """Array printing function
  2. $Id: arrayprint.py,v 1.9 2005/09/13 13:58:44 teoliphant Exp $
  3. """
  4. __all__ = ["array2string", "array_str", "array_repr",
  5. "set_printoptions", "get_printoptions", "printoptions",
  6. "format_float_positional", "format_float_scientific"]
  7. __docformat__ = 'restructuredtext'
  8. #
  9. # Written by Konrad Hinsen <hinsenk@ere.umontreal.ca>
  10. # last revision: 1996-3-13
  11. # modified by Jim Hugunin 1997-3-3 for repr's and str's (and other details)
  12. # and by Perry Greenfield 2000-4-1 for numarray
  13. # and by Travis Oliphant 2005-8-22 for numpy
  14. # Note: Both scalartypes.c.src and arrayprint.py implement strs for numpy
  15. # scalars but for different purposes. scalartypes.c.src has str/reprs for when
  16. # the scalar is printed on its own, while arrayprint.py has strs for when
  17. # scalars are printed inside an ndarray. Only the latter strs are currently
  18. # user-customizable.
  19. import functools
  20. import numbers
  21. import sys
  22. try:
  23. from _thread import get_ident
  24. except ImportError:
  25. from _dummy_thread import get_ident
  26. import numpy as np
  27. from . import numerictypes as _nt
  28. from .umath import absolute, isinf, isfinite, isnat
  29. from . import multiarray
  30. from .multiarray import (array, dragon4_positional, dragon4_scientific,
  31. datetime_as_string, datetime_data, ndarray)
  32. from .fromnumeric import any
  33. from .numeric import concatenate, asarray, errstate
  34. from .numerictypes import (longlong, intc, int_, float64, complex128,
  35. flexible)
  36. from .overrides import array_function_dispatch, set_module
  37. from .printoptions import format_options
  38. import operator
  39. import warnings
  40. import contextlib
  41. def _make_options_dict(precision=None, threshold=None, edgeitems=None,
  42. linewidth=None, suppress=None, nanstr=None, infstr=None,
  43. sign=None, formatter=None, floatmode=None, legacy=None,
  44. override_repr=None):
  45. """
  46. Make a dictionary out of the non-None arguments, plus conversion of
  47. *legacy* and sanity checks.
  48. """
  49. options = {k: v for k, v in list(locals().items()) if v is not None}
  50. if suppress is not None:
  51. options['suppress'] = bool(suppress)
  52. modes = ['fixed', 'unique', 'maxprec', 'maxprec_equal']
  53. if floatmode not in modes + [None]:
  54. raise ValueError("floatmode option must be one of " +
  55. ", ".join('"{}"'.format(m) for m in modes))
  56. if sign not in [None, '-', '+', ' ']:
  57. raise ValueError("sign option must be one of ' ', '+', or '-'")
  58. if legacy is False:
  59. options['legacy'] = sys.maxsize
  60. elif legacy == False: # noqa: E712
  61. warnings.warn(
  62. f"Passing `legacy={legacy!r}` is deprecated.",
  63. FutureWarning, stacklevel=3
  64. )
  65. options['legacy'] = sys.maxsize
  66. elif legacy == '1.13':
  67. options['legacy'] = 113
  68. elif legacy == '1.21':
  69. options['legacy'] = 121
  70. elif legacy == '1.25':
  71. options['legacy'] = 125
  72. elif legacy == '2.1':
  73. options['legacy'] = 201
  74. elif legacy is None:
  75. pass # OK, do nothing.
  76. else:
  77. warnings.warn(
  78. "legacy printing option can currently only be '1.13', '1.21', "
  79. "'1.25', '2.1, or `False`", stacklevel=3)
  80. if threshold is not None:
  81. # forbid the bad threshold arg suggested by stack overflow, gh-12351
  82. if not isinstance(threshold, numbers.Number):
  83. raise TypeError("threshold must be numeric")
  84. if np.isnan(threshold):
  85. raise ValueError("threshold must be non-NAN, try "
  86. "sys.maxsize for untruncated representation")
  87. if precision is not None:
  88. # forbid the bad precision arg as suggested by issue #18254
  89. try:
  90. options['precision'] = operator.index(precision)
  91. except TypeError as e:
  92. raise TypeError('precision must be an integer') from e
  93. return options
  94. @set_module('numpy')
  95. def set_printoptions(precision=None, threshold=None, edgeitems=None,
  96. linewidth=None, suppress=None, nanstr=None,
  97. infstr=None, formatter=None, sign=None, floatmode=None,
  98. *, legacy=None, override_repr=None):
  99. """
  100. Set printing options.
  101. These options determine the way floating point numbers, arrays and
  102. other NumPy objects are displayed.
  103. Parameters
  104. ----------
  105. precision : int or None, optional
  106. Number of digits of precision for floating point output (default 8).
  107. May be None if `floatmode` is not `fixed`, to print as many digits as
  108. necessary to uniquely specify the value.
  109. threshold : int, optional
  110. Total number of array elements which trigger summarization
  111. rather than full repr (default 1000).
  112. To always use the full repr without summarization, pass `sys.maxsize`.
  113. edgeitems : int, optional
  114. Number of array items in summary at beginning and end of
  115. each dimension (default 3).
  116. linewidth : int, optional
  117. The number of characters per line for the purpose of inserting
  118. line breaks (default 75).
  119. suppress : bool, optional
  120. If True, always print floating point numbers using fixed point
  121. notation, in which case numbers equal to zero in the current precision
  122. will print as zero. If False, then scientific notation is used when
  123. absolute value of the smallest number is < 1e-4 or the ratio of the
  124. maximum absolute value to the minimum is > 1e3. The default is False.
  125. nanstr : str, optional
  126. String representation of floating point not-a-number (default nan).
  127. infstr : str, optional
  128. String representation of floating point infinity (default inf).
  129. sign : string, either '-', '+', or ' ', optional
  130. Controls printing of the sign of floating-point types. If '+', always
  131. print the sign of positive values. If ' ', always prints a space
  132. (whitespace character) in the sign position of positive values. If
  133. '-', omit the sign character of positive values. (default '-')
  134. .. versionchanged:: 2.0
  135. The sign parameter can now be an integer type, previously
  136. types were floating-point types.
  137. formatter : dict of callables, optional
  138. If not None, the keys should indicate the type(s) that the respective
  139. formatting function applies to. Callables should return a string.
  140. Types that are not specified (by their corresponding keys) are handled
  141. by the default formatters. Individual types for which a formatter
  142. can be set are:
  143. - 'bool'
  144. - 'int'
  145. - 'timedelta' : a `numpy.timedelta64`
  146. - 'datetime' : a `numpy.datetime64`
  147. - 'float'
  148. - 'longfloat' : 128-bit floats
  149. - 'complexfloat'
  150. - 'longcomplexfloat' : composed of two 128-bit floats
  151. - 'numpystr' : types `numpy.bytes_` and `numpy.str_`
  152. - 'object' : `np.object_` arrays
  153. Other keys that can be used to set a group of types at once are:
  154. - 'all' : sets all types
  155. - 'int_kind' : sets 'int'
  156. - 'float_kind' : sets 'float' and 'longfloat'
  157. - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
  158. - 'str_kind' : sets 'numpystr'
  159. floatmode : str, optional
  160. Controls the interpretation of the `precision` option for
  161. floating-point types. Can take the following values
  162. (default maxprec_equal):
  163. * 'fixed': Always print exactly `precision` fractional digits,
  164. even if this would print more or fewer digits than
  165. necessary to specify the value uniquely.
  166. * 'unique': Print the minimum number of fractional digits necessary
  167. to represent each value uniquely. Different elements may
  168. have a different number of digits. The value of the
  169. `precision` option is ignored.
  170. * 'maxprec': Print at most `precision` fractional digits, but if
  171. an element can be uniquely represented with fewer digits
  172. only print it with that many.
  173. * 'maxprec_equal': Print at most `precision` fractional digits,
  174. but if every element in the array can be uniquely
  175. represented with an equal number of fewer digits, use that
  176. many digits for all elements.
  177. legacy : string or `False`, optional
  178. If set to the string ``'1.13'`` enables 1.13 legacy printing mode. This
  179. approximates numpy 1.13 print output by including a space in the sign
  180. position of floats and different behavior for 0d arrays. This also
  181. enables 1.21 legacy printing mode (described below).
  182. If set to the string ``'1.21'`` enables 1.21 legacy printing mode. This
  183. approximates numpy 1.21 print output of complex structured dtypes
  184. by not inserting spaces after commas that separate fields and after
  185. colons.
  186. If set to ``'1.25'`` approximates printing of 1.25 which mainly means
  187. that numeric scalars are printed without their type information, e.g.
  188. as ``3.0`` rather than ``np.float64(3.0)``.
  189. If set to ``'2.1'``, shape information is not given when arrays are
  190. summarized (i.e., multiple elements replaced with ``...``).
  191. If set to `False`, disables legacy mode.
  192. Unrecognized strings will be ignored with a warning for forward
  193. compatibility.
  194. .. versionchanged:: 1.22.0
  195. .. versionchanged:: 2.2
  196. override_repr: callable, optional
  197. If set a passed function will be used for generating arrays' repr.
  198. Other options will be ignored.
  199. See Also
  200. --------
  201. get_printoptions, printoptions, array2string
  202. Notes
  203. -----
  204. `formatter` is always reset with a call to `set_printoptions`.
  205. Use `printoptions` as a context manager to set the values temporarily.
  206. Examples
  207. --------
  208. Floating point precision can be set:
  209. >>> import numpy as np
  210. >>> np.set_printoptions(precision=4)
  211. >>> np.array([1.123456789])
  212. [1.1235]
  213. Long arrays can be summarised:
  214. >>> np.set_printoptions(threshold=5)
  215. >>> np.arange(10)
  216. array([0, 1, 2, ..., 7, 8, 9], shape=(10,))
  217. Small results can be suppressed:
  218. >>> eps = np.finfo(float).eps
  219. >>> x = np.arange(4.)
  220. >>> x**2 - (x + eps)**2
  221. array([-4.9304e-32, -4.4409e-16, 0.0000e+00, 0.0000e+00])
  222. >>> np.set_printoptions(suppress=True)
  223. >>> x**2 - (x + eps)**2
  224. array([-0., -0., 0., 0.])
  225. A custom formatter can be used to display array elements as desired:
  226. >>> np.set_printoptions(formatter={'all':lambda x: 'int: '+str(-x)})
  227. >>> x = np.arange(3)
  228. >>> x
  229. array([int: 0, int: -1, int: -2])
  230. >>> np.set_printoptions() # formatter gets reset
  231. >>> x
  232. array([0, 1, 2])
  233. To put back the default options, you can use:
  234. >>> np.set_printoptions(edgeitems=3, infstr='inf',
  235. ... linewidth=75, nanstr='nan', precision=8,
  236. ... suppress=False, threshold=1000, formatter=None)
  237. Also to temporarily override options, use `printoptions`
  238. as a context manager:
  239. >>> with np.printoptions(precision=2, suppress=True, threshold=5):
  240. ... np.linspace(0, 10, 10)
  241. array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ], shape=(10,))
  242. """
  243. _set_printoptions(precision, threshold, edgeitems, linewidth, suppress,
  244. nanstr, infstr, formatter, sign, floatmode,
  245. legacy=legacy, override_repr=override_repr)
  246. def _set_printoptions(precision=None, threshold=None, edgeitems=None,
  247. linewidth=None, suppress=None, nanstr=None,
  248. infstr=None, formatter=None, sign=None, floatmode=None,
  249. *, legacy=None, override_repr=None):
  250. new_opt = _make_options_dict(precision, threshold, edgeitems, linewidth,
  251. suppress, nanstr, infstr, sign, formatter,
  252. floatmode, legacy)
  253. # formatter and override_repr are always reset
  254. new_opt['formatter'] = formatter
  255. new_opt['override_repr'] = override_repr
  256. updated_opt = format_options.get() | new_opt
  257. updated_opt.update(new_opt)
  258. if updated_opt['legacy'] == 113:
  259. updated_opt['sign'] = '-'
  260. return format_options.set(updated_opt)
  261. @set_module('numpy')
  262. def get_printoptions():
  263. """
  264. Return the current print options.
  265. Returns
  266. -------
  267. print_opts : dict
  268. Dictionary of current print options with keys
  269. - precision : int
  270. - threshold : int
  271. - edgeitems : int
  272. - linewidth : int
  273. - suppress : bool
  274. - nanstr : str
  275. - infstr : str
  276. - sign : str
  277. - formatter : dict of callables
  278. - floatmode : str
  279. - legacy : str or False
  280. For a full description of these options, see `set_printoptions`.
  281. See Also
  282. --------
  283. set_printoptions, printoptions
  284. Examples
  285. --------
  286. >>> import numpy as np
  287. >>> np.get_printoptions()
  288. {'edgeitems': 3, 'threshold': 1000, ..., 'override_repr': None}
  289. >>> np.get_printoptions()['linewidth']
  290. 75
  291. >>> np.set_printoptions(linewidth=100)
  292. >>> np.get_printoptions()['linewidth']
  293. 100
  294. """
  295. opts = format_options.get().copy()
  296. opts['legacy'] = {
  297. 113: '1.13', 121: '1.21', 125: '1.25', sys.maxsize: False,
  298. }[opts['legacy']]
  299. return opts
  300. def _get_legacy_print_mode():
  301. """Return the legacy print mode as an int."""
  302. return format_options.get()['legacy']
  303. @set_module('numpy')
  304. @contextlib.contextmanager
  305. def printoptions(*args, **kwargs):
  306. """Context manager for setting print options.
  307. Set print options for the scope of the `with` block, and restore the old
  308. options at the end. See `set_printoptions` for the full description of
  309. available options.
  310. Examples
  311. --------
  312. >>> import numpy as np
  313. >>> from numpy.testing import assert_equal
  314. >>> with np.printoptions(precision=2):
  315. ... np.array([2.0]) / 3
  316. array([0.67])
  317. The `as`-clause of the `with`-statement gives the current print options:
  318. >>> with np.printoptions(precision=2) as opts:
  319. ... assert_equal(opts, np.get_printoptions())
  320. See Also
  321. --------
  322. set_printoptions, get_printoptions
  323. """
  324. token = _set_printoptions(*args, **kwargs)
  325. try:
  326. yield get_printoptions()
  327. finally:
  328. format_options.reset(token)
  329. def _leading_trailing(a, edgeitems, index=()):
  330. """
  331. Keep only the N-D corners (leading and trailing edges) of an array.
  332. Should be passed a base-class ndarray, since it makes no guarantees about
  333. preserving subclasses.
  334. """
  335. axis = len(index)
  336. if axis == a.ndim:
  337. return a[index]
  338. if a.shape[axis] > 2*edgeitems:
  339. return concatenate((
  340. _leading_trailing(a, edgeitems, index + np.index_exp[:edgeitems]),
  341. _leading_trailing(a, edgeitems, index + np.index_exp[-edgeitems:])
  342. ), axis=axis)
  343. else:
  344. return _leading_trailing(a, edgeitems, index + np.index_exp[:])
  345. def _object_format(o):
  346. """ Object arrays containing lists should be printed unambiguously """
  347. if type(o) is list:
  348. fmt = 'list({!r})'
  349. else:
  350. fmt = '{!r}'
  351. return fmt.format(o)
  352. def repr_format(x):
  353. if isinstance(x, (np.str_, np.bytes_)):
  354. return repr(x.item())
  355. return repr(x)
  356. def str_format(x):
  357. if isinstance(x, (np.str_, np.bytes_)):
  358. return str(x.item())
  359. return str(x)
  360. def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy,
  361. formatter, **kwargs):
  362. # note: extra arguments in kwargs are ignored
  363. # wrapped in lambdas to avoid taking a code path
  364. # with the wrong type of data
  365. formatdict = {
  366. 'bool': lambda: BoolFormat(data),
  367. 'int': lambda: IntegerFormat(data, sign),
  368. 'float': lambda: FloatingFormat(
  369. data, precision, floatmode, suppress, sign, legacy=legacy),
  370. 'longfloat': lambda: FloatingFormat(
  371. data, precision, floatmode, suppress, sign, legacy=legacy),
  372. 'complexfloat': lambda: ComplexFloatingFormat(
  373. data, precision, floatmode, suppress, sign, legacy=legacy),
  374. 'longcomplexfloat': lambda: ComplexFloatingFormat(
  375. data, precision, floatmode, suppress, sign, legacy=legacy),
  376. 'datetime': lambda: DatetimeFormat(data, legacy=legacy),
  377. 'timedelta': lambda: TimedeltaFormat(data),
  378. 'object': lambda: _object_format,
  379. 'void': lambda: str_format,
  380. 'numpystr': lambda: repr_format}
  381. # we need to wrap values in `formatter` in a lambda, so that the interface
  382. # is the same as the above values.
  383. def indirect(x):
  384. return lambda: x
  385. if formatter is not None:
  386. fkeys = [k for k in formatter.keys() if formatter[k] is not None]
  387. if 'all' in fkeys:
  388. for key in formatdict.keys():
  389. formatdict[key] = indirect(formatter['all'])
  390. if 'int_kind' in fkeys:
  391. for key in ['int']:
  392. formatdict[key] = indirect(formatter['int_kind'])
  393. if 'float_kind' in fkeys:
  394. for key in ['float', 'longfloat']:
  395. formatdict[key] = indirect(formatter['float_kind'])
  396. if 'complex_kind' in fkeys:
  397. for key in ['complexfloat', 'longcomplexfloat']:
  398. formatdict[key] = indirect(formatter['complex_kind'])
  399. if 'str_kind' in fkeys:
  400. formatdict['numpystr'] = indirect(formatter['str_kind'])
  401. for key in formatdict.keys():
  402. if key in fkeys:
  403. formatdict[key] = indirect(formatter[key])
  404. return formatdict
  405. def _get_format_function(data, **options):
  406. """
  407. find the right formatting function for the dtype_
  408. """
  409. dtype_ = data.dtype
  410. dtypeobj = dtype_.type
  411. formatdict = _get_formatdict(data, **options)
  412. if dtypeobj is None:
  413. return formatdict["numpystr"]()
  414. elif issubclass(dtypeobj, _nt.bool):
  415. return formatdict['bool']()
  416. elif issubclass(dtypeobj, _nt.integer):
  417. if issubclass(dtypeobj, _nt.timedelta64):
  418. return formatdict['timedelta']()
  419. else:
  420. return formatdict['int']()
  421. elif issubclass(dtypeobj, _nt.floating):
  422. if issubclass(dtypeobj, _nt.longdouble):
  423. return formatdict['longfloat']()
  424. else:
  425. return formatdict['float']()
  426. elif issubclass(dtypeobj, _nt.complexfloating):
  427. if issubclass(dtypeobj, _nt.clongdouble):
  428. return formatdict['longcomplexfloat']()
  429. else:
  430. return formatdict['complexfloat']()
  431. elif issubclass(dtypeobj, (_nt.str_, _nt.bytes_)):
  432. return formatdict['numpystr']()
  433. elif issubclass(dtypeobj, _nt.datetime64):
  434. return formatdict['datetime']()
  435. elif issubclass(dtypeobj, _nt.object_):
  436. return formatdict['object']()
  437. elif issubclass(dtypeobj, _nt.void):
  438. if dtype_.names is not None:
  439. return StructuredVoidFormat.from_data(data, **options)
  440. else:
  441. return formatdict['void']()
  442. else:
  443. return formatdict['numpystr']()
  444. def _recursive_guard(fillvalue='...'):
  445. """
  446. Like the python 3.2 reprlib.recursive_repr, but forwards *args and **kwargs
  447. Decorates a function such that if it calls itself with the same first
  448. argument, it returns `fillvalue` instead of recursing.
  449. Largely copied from reprlib.recursive_repr
  450. """
  451. def decorating_function(f):
  452. repr_running = set()
  453. @functools.wraps(f)
  454. def wrapper(self, *args, **kwargs):
  455. key = id(self), get_ident()
  456. if key in repr_running:
  457. return fillvalue
  458. repr_running.add(key)
  459. try:
  460. return f(self, *args, **kwargs)
  461. finally:
  462. repr_running.discard(key)
  463. return wrapper
  464. return decorating_function
  465. # gracefully handle recursive calls, when object arrays contain themselves
  466. @_recursive_guard()
  467. def _array2string(a, options, separator=' ', prefix=""):
  468. # The formatter __init__s in _get_format_function cannot deal with
  469. # subclasses yet, and we also need to avoid recursion issues in
  470. # _formatArray with subclasses which return 0d arrays in place of scalars
  471. data = asarray(a)
  472. if a.shape == ():
  473. a = data
  474. if a.size > options['threshold']:
  475. summary_insert = "..."
  476. data = _leading_trailing(data, options['edgeitems'])
  477. else:
  478. summary_insert = ""
  479. # find the right formatting function for the array
  480. format_function = _get_format_function(data, **options)
  481. # skip over "["
  482. next_line_prefix = " "
  483. # skip over array(
  484. next_line_prefix += " "*len(prefix)
  485. lst = _formatArray(a, format_function, options['linewidth'],
  486. next_line_prefix, separator, options['edgeitems'],
  487. summary_insert, options['legacy'])
  488. return lst
  489. def _array2string_dispatcher(
  490. a, max_line_width=None, precision=None,
  491. suppress_small=None, separator=None, prefix=None,
  492. style=None, formatter=None, threshold=None,
  493. edgeitems=None, sign=None, floatmode=None, suffix=None,
  494. *, legacy=None):
  495. return (a,)
  496. @array_function_dispatch(_array2string_dispatcher, module='numpy')
  497. def array2string(a, max_line_width=None, precision=None,
  498. suppress_small=None, separator=' ', prefix="",
  499. style=np._NoValue, formatter=None, threshold=None,
  500. edgeitems=None, sign=None, floatmode=None, suffix="",
  501. *, legacy=None):
  502. """
  503. Return a string representation of an array.
  504. Parameters
  505. ----------
  506. a : ndarray
  507. Input array.
  508. max_line_width : int, optional
  509. Inserts newlines if text is longer than `max_line_width`.
  510. Defaults to ``numpy.get_printoptions()['linewidth']``.
  511. precision : int or None, optional
  512. Floating point precision.
  513. Defaults to ``numpy.get_printoptions()['precision']``.
  514. suppress_small : bool, optional
  515. Represent numbers "very close" to zero as zero; default is False.
  516. Very close is defined by precision: if the precision is 8, e.g.,
  517. numbers smaller (in absolute value) than 5e-9 are represented as
  518. zero.
  519. Defaults to ``numpy.get_printoptions()['suppress']``.
  520. separator : str, optional
  521. Inserted between elements.
  522. prefix : str, optional
  523. suffix : str, optional
  524. The length of the prefix and suffix strings are used to respectively
  525. align and wrap the output. An array is typically printed as::
  526. prefix + array2string(a) + suffix
  527. The output is left-padded by the length of the prefix string, and
  528. wrapping is forced at the column ``max_line_width - len(suffix)``.
  529. It should be noted that the content of prefix and suffix strings are
  530. not included in the output.
  531. style : _NoValue, optional
  532. Has no effect, do not use.
  533. .. deprecated:: 1.14.0
  534. formatter : dict of callables, optional
  535. If not None, the keys should indicate the type(s) that the respective
  536. formatting function applies to. Callables should return a string.
  537. Types that are not specified (by their corresponding keys) are handled
  538. by the default formatters. Individual types for which a formatter
  539. can be set are:
  540. - 'bool'
  541. - 'int'
  542. - 'timedelta' : a `numpy.timedelta64`
  543. - 'datetime' : a `numpy.datetime64`
  544. - 'float'
  545. - 'longfloat' : 128-bit floats
  546. - 'complexfloat'
  547. - 'longcomplexfloat' : composed of two 128-bit floats
  548. - 'void' : type `numpy.void`
  549. - 'numpystr' : types `numpy.bytes_` and `numpy.str_`
  550. Other keys that can be used to set a group of types at once are:
  551. - 'all' : sets all types
  552. - 'int_kind' : sets 'int'
  553. - 'float_kind' : sets 'float' and 'longfloat'
  554. - 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
  555. - 'str_kind' : sets 'numpystr'
  556. threshold : int, optional
  557. Total number of array elements which trigger summarization
  558. rather than full repr.
  559. Defaults to ``numpy.get_printoptions()['threshold']``.
  560. edgeitems : int, optional
  561. Number of array items in summary at beginning and end of
  562. each dimension.
  563. Defaults to ``numpy.get_printoptions()['edgeitems']``.
  564. sign : string, either '-', '+', or ' ', optional
  565. Controls printing of the sign of floating-point types. If '+', always
  566. print the sign of positive values. If ' ', always prints a space
  567. (whitespace character) in the sign position of positive values. If
  568. '-', omit the sign character of positive values.
  569. Defaults to ``numpy.get_printoptions()['sign']``.
  570. .. versionchanged:: 2.0
  571. The sign parameter can now be an integer type, previously
  572. types were floating-point types.
  573. floatmode : str, optional
  574. Controls the interpretation of the `precision` option for
  575. floating-point types.
  576. Defaults to ``numpy.get_printoptions()['floatmode']``.
  577. Can take the following values:
  578. - 'fixed': Always print exactly `precision` fractional digits,
  579. even if this would print more or fewer digits than
  580. necessary to specify the value uniquely.
  581. - 'unique': Print the minimum number of fractional digits necessary
  582. to represent each value uniquely. Different elements may
  583. have a different number of digits. The value of the
  584. `precision` option is ignored.
  585. - 'maxprec': Print at most `precision` fractional digits, but if
  586. an element can be uniquely represented with fewer digits
  587. only print it with that many.
  588. - 'maxprec_equal': Print at most `precision` fractional digits,
  589. but if every element in the array can be uniquely
  590. represented with an equal number of fewer digits, use that
  591. many digits for all elements.
  592. legacy : string or `False`, optional
  593. If set to the string ``'1.13'`` enables 1.13 legacy printing mode. This
  594. approximates numpy 1.13 print output by including a space in the sign
  595. position of floats and different behavior for 0d arrays. If set to
  596. `False`, disables legacy mode. Unrecognized strings will be ignored
  597. with a warning for forward compatibility.
  598. Returns
  599. -------
  600. array_str : str
  601. String representation of the array.
  602. Raises
  603. ------
  604. TypeError
  605. if a callable in `formatter` does not return a string.
  606. See Also
  607. --------
  608. array_str, array_repr, set_printoptions, get_printoptions
  609. Notes
  610. -----
  611. If a formatter is specified for a certain type, the `precision` keyword is
  612. ignored for that type.
  613. This is a very flexible function; `array_repr` and `array_str` are using
  614. `array2string` internally so keywords with the same name should work
  615. identically in all three functions.
  616. Examples
  617. --------
  618. >>> import numpy as np
  619. >>> x = np.array([1e-16,1,2,3])
  620. >>> np.array2string(x, precision=2, separator=',',
  621. ... suppress_small=True)
  622. '[0.,1.,2.,3.]'
  623. >>> x = np.arange(3.)
  624. >>> np.array2string(x, formatter={'float_kind':lambda x: "%.2f" % x})
  625. '[0.00 1.00 2.00]'
  626. >>> x = np.arange(3)
  627. >>> np.array2string(x, formatter={'int':lambda x: hex(x)})
  628. '[0x0 0x1 0x2]'
  629. """
  630. overrides = _make_options_dict(precision, threshold, edgeitems,
  631. max_line_width, suppress_small, None, None,
  632. sign, formatter, floatmode, legacy)
  633. options = format_options.get().copy()
  634. options.update(overrides)
  635. if options['legacy'] <= 113:
  636. if style is np._NoValue:
  637. style = repr
  638. if a.shape == () and a.dtype.names is None:
  639. return style(a.item())
  640. elif style is not np._NoValue:
  641. # Deprecation 11-9-2017 v1.14
  642. warnings.warn("'style' argument is deprecated and no longer functional"
  643. " except in 1.13 'legacy' mode",
  644. DeprecationWarning, stacklevel=2)
  645. if options['legacy'] > 113:
  646. options['linewidth'] -= len(suffix)
  647. # treat as a null array if any of shape elements == 0
  648. if a.size == 0:
  649. return "[]"
  650. return _array2string(a, options, separator, prefix)
  651. def _extendLine(s, line, word, line_width, next_line_prefix, legacy):
  652. needs_wrap = len(line) + len(word) > line_width
  653. if legacy > 113:
  654. # don't wrap lines if it won't help
  655. if len(line) <= len(next_line_prefix):
  656. needs_wrap = False
  657. if needs_wrap:
  658. s += line.rstrip() + "\n"
  659. line = next_line_prefix
  660. line += word
  661. return s, line
  662. def _extendLine_pretty(s, line, word, line_width, next_line_prefix, legacy):
  663. """
  664. Extends line with nicely formatted (possibly multi-line) string ``word``.
  665. """
  666. words = word.splitlines()
  667. if len(words) == 1 or legacy <= 113:
  668. return _extendLine(s, line, word, line_width, next_line_prefix, legacy)
  669. max_word_length = max(len(word) for word in words)
  670. if (len(line) + max_word_length > line_width and
  671. len(line) > len(next_line_prefix)):
  672. s += line.rstrip() + '\n'
  673. line = next_line_prefix + words[0]
  674. indent = next_line_prefix
  675. else:
  676. indent = len(line)*' '
  677. line += words[0]
  678. for word in words[1::]:
  679. s += line.rstrip() + '\n'
  680. line = indent + word
  681. suffix_length = max_word_length - len(words[-1])
  682. line += suffix_length*' '
  683. return s, line
  684. def _formatArray(a, format_function, line_width, next_line_prefix,
  685. separator, edge_items, summary_insert, legacy):
  686. """formatArray is designed for two modes of operation:
  687. 1. Full output
  688. 2. Summarized output
  689. """
  690. def recurser(index, hanging_indent, curr_width):
  691. """
  692. By using this local function, we don't need to recurse with all the
  693. arguments. Since this function is not created recursively, the cost is
  694. not significant
  695. """
  696. axis = len(index)
  697. axes_left = a.ndim - axis
  698. if axes_left == 0:
  699. return format_function(a[index])
  700. # when recursing, add a space to align with the [ added, and reduce the
  701. # length of the line by 1
  702. next_hanging_indent = hanging_indent + ' '
  703. if legacy <= 113:
  704. next_width = curr_width
  705. else:
  706. next_width = curr_width - len(']')
  707. a_len = a.shape[axis]
  708. show_summary = summary_insert and 2*edge_items < a_len
  709. if show_summary:
  710. leading_items = edge_items
  711. trailing_items = edge_items
  712. else:
  713. leading_items = 0
  714. trailing_items = a_len
  715. # stringify the array with the hanging indent on the first line too
  716. s = ''
  717. # last axis (rows) - wrap elements if they would not fit on one line
  718. if axes_left == 1:
  719. # the length up until the beginning of the separator / bracket
  720. if legacy <= 113:
  721. elem_width = curr_width - len(separator.rstrip())
  722. else:
  723. elem_width = curr_width - max(
  724. len(separator.rstrip()), len(']')
  725. )
  726. line = hanging_indent
  727. for i in range(leading_items):
  728. word = recurser(index + (i,), next_hanging_indent, next_width)
  729. s, line = _extendLine_pretty(
  730. s, line, word, elem_width, hanging_indent, legacy)
  731. line += separator
  732. if show_summary:
  733. s, line = _extendLine(
  734. s, line, summary_insert, elem_width, hanging_indent, legacy
  735. )
  736. if legacy <= 113:
  737. line += ", "
  738. else:
  739. line += separator
  740. for i in range(trailing_items, 1, -1):
  741. word = recurser(index + (-i,), next_hanging_indent, next_width)
  742. s, line = _extendLine_pretty(
  743. s, line, word, elem_width, hanging_indent, legacy)
  744. line += separator
  745. if legacy <= 113:
  746. # width of the separator is not considered on 1.13
  747. elem_width = curr_width
  748. word = recurser(index + (-1,), next_hanging_indent, next_width)
  749. s, line = _extendLine_pretty(
  750. s, line, word, elem_width, hanging_indent, legacy)
  751. s += line
  752. # other axes - insert newlines between rows
  753. else:
  754. s = ''
  755. line_sep = separator.rstrip() + '\n'*(axes_left - 1)
  756. for i in range(leading_items):
  757. nested = recurser(
  758. index + (i,), next_hanging_indent, next_width
  759. )
  760. s += hanging_indent + nested + line_sep
  761. if show_summary:
  762. if legacy <= 113:
  763. # trailing space, fixed nbr of newlines,
  764. # and fixed separator
  765. s += hanging_indent + summary_insert + ", \n"
  766. else:
  767. s += hanging_indent + summary_insert + line_sep
  768. for i in range(trailing_items, 1, -1):
  769. nested = recurser(index + (-i,), next_hanging_indent,
  770. next_width)
  771. s += hanging_indent + nested + line_sep
  772. nested = recurser(index + (-1,), next_hanging_indent, next_width)
  773. s += hanging_indent + nested
  774. # remove the hanging indent, and wrap in []
  775. s = '[' + s[len(hanging_indent):] + ']'
  776. return s
  777. try:
  778. # invoke the recursive part with an initial index and prefix
  779. return recurser(index=(),
  780. hanging_indent=next_line_prefix,
  781. curr_width=line_width)
  782. finally:
  783. # recursive closures have a cyclic reference to themselves, which
  784. # requires gc to collect (gh-10620). To avoid this problem, for
  785. # performance and PyPy friendliness, we break the cycle:
  786. recurser = None
  787. def _none_or_positive_arg(x, name):
  788. if x is None:
  789. return -1
  790. if x < 0:
  791. raise ValueError("{} must be >= 0".format(name))
  792. return x
  793. class FloatingFormat:
  794. """ Formatter for subtypes of np.floating """
  795. def __init__(self, data, precision, floatmode, suppress_small, sign=False,
  796. *, legacy=None):
  797. # for backcompatibility, accept bools
  798. if isinstance(sign, bool):
  799. sign = '+' if sign else '-'
  800. self._legacy = legacy
  801. if self._legacy <= 113:
  802. # when not 0d, legacy does not support '-'
  803. if data.shape != () and sign == '-':
  804. sign = ' '
  805. self.floatmode = floatmode
  806. if floatmode == 'unique':
  807. self.precision = None
  808. else:
  809. self.precision = precision
  810. self.precision = _none_or_positive_arg(self.precision, 'precision')
  811. self.suppress_small = suppress_small
  812. self.sign = sign
  813. self.exp_format = False
  814. self.large_exponent = False
  815. self.fillFormat(data)
  816. def fillFormat(self, data):
  817. # only the finite values are used to compute the number of digits
  818. finite_vals = data[isfinite(data)]
  819. # choose exponential mode based on the non-zero finite values:
  820. abs_non_zero = absolute(finite_vals[finite_vals != 0])
  821. if len(abs_non_zero) != 0:
  822. max_val = np.max(abs_non_zero)
  823. min_val = np.min(abs_non_zero)
  824. with errstate(over='ignore'): # division can overflow
  825. if max_val >= 1.e8 or (not self.suppress_small and
  826. (min_val < 0.0001 or max_val/min_val > 1000.)):
  827. self.exp_format = True
  828. # do a first pass of printing all the numbers, to determine sizes
  829. if len(finite_vals) == 0:
  830. self.pad_left = 0
  831. self.pad_right = 0
  832. self.trim = '.'
  833. self.exp_size = -1
  834. self.unique = True
  835. self.min_digits = None
  836. elif self.exp_format:
  837. trim, unique = '.', True
  838. if self.floatmode == 'fixed' or self._legacy <= 113:
  839. trim, unique = 'k', False
  840. strs = (dragon4_scientific(x, precision=self.precision,
  841. unique=unique, trim=trim, sign=self.sign == '+')
  842. for x in finite_vals)
  843. frac_strs, _, exp_strs = zip(*(s.partition('e') for s in strs))
  844. int_part, frac_part = zip(*(s.split('.') for s in frac_strs))
  845. self.exp_size = max(len(s) for s in exp_strs) - 1
  846. self.trim = 'k'
  847. self.precision = max(len(s) for s in frac_part)
  848. self.min_digits = self.precision
  849. self.unique = unique
  850. # for back-compat with np 1.13, use 2 spaces & sign and full prec
  851. if self._legacy <= 113:
  852. self.pad_left = 3
  853. else:
  854. # this should be only 1 or 2. Can be calculated from sign.
  855. self.pad_left = max(len(s) for s in int_part)
  856. # pad_right is only needed for nan length calculation
  857. self.pad_right = self.exp_size + 2 + self.precision
  858. else:
  859. trim, unique = '.', True
  860. if self.floatmode == 'fixed':
  861. trim, unique = 'k', False
  862. strs = (dragon4_positional(x, precision=self.precision,
  863. fractional=True,
  864. unique=unique, trim=trim,
  865. sign=self.sign == '+')
  866. for x in finite_vals)
  867. int_part, frac_part = zip(*(s.split('.') for s in strs))
  868. if self._legacy <= 113:
  869. self.pad_left = 1 + max(len(s.lstrip('-+')) for s in int_part)
  870. else:
  871. self.pad_left = max(len(s) for s in int_part)
  872. self.pad_right = max(len(s) for s in frac_part)
  873. self.exp_size = -1
  874. self.unique = unique
  875. if self.floatmode in ['fixed', 'maxprec_equal']:
  876. self.precision = self.min_digits = self.pad_right
  877. self.trim = 'k'
  878. else:
  879. self.trim = '.'
  880. self.min_digits = 0
  881. if self._legacy > 113:
  882. # account for sign = ' ' by adding one to pad_left
  883. if self.sign == ' ' and not any(np.signbit(finite_vals)):
  884. self.pad_left += 1
  885. # if there are non-finite values, may need to increase pad_left
  886. if data.size != finite_vals.size:
  887. neginf = self.sign != '-' or any(data[isinf(data)] < 0)
  888. offset = self.pad_right + 1 # +1 for decimal pt
  889. current_options = format_options.get()
  890. self.pad_left = max(
  891. self.pad_left, len(current_options['nanstr']) - offset,
  892. len(current_options['infstr']) + neginf - offset
  893. )
  894. def __call__(self, x):
  895. if not np.isfinite(x):
  896. with errstate(invalid='ignore'):
  897. current_options = format_options.get()
  898. if np.isnan(x):
  899. sign = '+' if self.sign == '+' else ''
  900. ret = sign + current_options['nanstr']
  901. else: # isinf
  902. sign = '-' if x < 0 else '+' if self.sign == '+' else ''
  903. ret = sign + current_options['infstr']
  904. return ' '*(
  905. self.pad_left + self.pad_right + 1 - len(ret)
  906. ) + ret
  907. if self.exp_format:
  908. return dragon4_scientific(x,
  909. precision=self.precision,
  910. min_digits=self.min_digits,
  911. unique=self.unique,
  912. trim=self.trim,
  913. sign=self.sign == '+',
  914. pad_left=self.pad_left,
  915. exp_digits=self.exp_size)
  916. else:
  917. return dragon4_positional(x,
  918. precision=self.precision,
  919. min_digits=self.min_digits,
  920. unique=self.unique,
  921. fractional=True,
  922. trim=self.trim,
  923. sign=self.sign == '+',
  924. pad_left=self.pad_left,
  925. pad_right=self.pad_right)
  926. @set_module('numpy')
  927. def format_float_scientific(x, precision=None, unique=True, trim='k',
  928. sign=False, pad_left=None, exp_digits=None,
  929. min_digits=None):
  930. """
  931. Format a floating-point scalar as a decimal string in scientific notation.
  932. Provides control over rounding, trimming and padding. Uses and assumes
  933. IEEE unbiased rounding. Uses the "Dragon4" algorithm.
  934. Parameters
  935. ----------
  936. x : python float or numpy floating scalar
  937. Value to format.
  938. precision : non-negative integer or None, optional
  939. Maximum number of digits to print. May be None if `unique` is
  940. `True`, but must be an integer if unique is `False`.
  941. unique : boolean, optional
  942. If `True`, use a digit-generation strategy which gives the shortest
  943. representation which uniquely identifies the floating-point number from
  944. other values of the same type, by judicious rounding. If `precision`
  945. is given fewer digits than necessary can be printed. If `min_digits`
  946. is given more can be printed, in which cases the last digit is rounded
  947. with unbiased rounding.
  948. If `False`, digits are generated as if printing an infinite-precision
  949. value and stopping after `precision` digits, rounding the remaining
  950. value with unbiased rounding
  951. trim : one of 'k', '.', '0', '-', optional
  952. Controls post-processing trimming of trailing digits, as follows:
  953. * 'k' : keep trailing zeros, keep decimal point (no trimming)
  954. * '.' : trim all trailing zeros, leave decimal point
  955. * '0' : trim all but the zero before the decimal point. Insert the
  956. zero if it is missing.
  957. * '-' : trim trailing zeros and any trailing decimal point
  958. sign : boolean, optional
  959. Whether to show the sign for positive values.
  960. pad_left : non-negative integer, optional
  961. Pad the left side of the string with whitespace until at least that
  962. many characters are to the left of the decimal point.
  963. exp_digits : non-negative integer, optional
  964. Pad the exponent with zeros until it contains at least this
  965. many digits. If omitted, the exponent will be at least 2 digits.
  966. min_digits : non-negative integer or None, optional
  967. Minimum number of digits to print. This only has an effect for
  968. `unique=True`. In that case more digits than necessary to uniquely
  969. identify the value may be printed and rounded unbiased.
  970. .. versionadded:: 1.21.0
  971. Returns
  972. -------
  973. rep : string
  974. The string representation of the floating point value
  975. See Also
  976. --------
  977. format_float_positional
  978. Examples
  979. --------
  980. >>> import numpy as np
  981. >>> np.format_float_scientific(np.float32(np.pi))
  982. '3.1415927e+00'
  983. >>> s = np.float32(1.23e24)
  984. >>> np.format_float_scientific(s, unique=False, precision=15)
  985. '1.230000071797338e+24'
  986. >>> np.format_float_scientific(s, exp_digits=4)
  987. '1.23e+0024'
  988. """
  989. precision = _none_or_positive_arg(precision, 'precision')
  990. pad_left = _none_or_positive_arg(pad_left, 'pad_left')
  991. exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits')
  992. min_digits = _none_or_positive_arg(min_digits, 'min_digits')
  993. if min_digits > 0 and precision > 0 and min_digits > precision:
  994. raise ValueError("min_digits must be less than or equal to precision")
  995. return dragon4_scientific(x, precision=precision, unique=unique,
  996. trim=trim, sign=sign, pad_left=pad_left,
  997. exp_digits=exp_digits, min_digits=min_digits)
  998. @set_module('numpy')
  999. def format_float_positional(x, precision=None, unique=True,
  1000. fractional=True, trim='k', sign=False,
  1001. pad_left=None, pad_right=None, min_digits=None):
  1002. """
  1003. Format a floating-point scalar as a decimal string in positional notation.
  1004. Provides control over rounding, trimming and padding. Uses and assumes
  1005. IEEE unbiased rounding. Uses the "Dragon4" algorithm.
  1006. Parameters
  1007. ----------
  1008. x : python float or numpy floating scalar
  1009. Value to format.
  1010. precision : non-negative integer or None, optional
  1011. Maximum number of digits to print. May be None if `unique` is
  1012. `True`, but must be an integer if unique is `False`.
  1013. unique : boolean, optional
  1014. If `True`, use a digit-generation strategy which gives the shortest
  1015. representation which uniquely identifies the floating-point number from
  1016. other values of the same type, by judicious rounding. If `precision`
  1017. is given fewer digits than necessary can be printed, or if `min_digits`
  1018. is given more can be printed, in which cases the last digit is rounded
  1019. with unbiased rounding.
  1020. If `False`, digits are generated as if printing an infinite-precision
  1021. value and stopping after `precision` digits, rounding the remaining
  1022. value with unbiased rounding
  1023. fractional : boolean, optional
  1024. If `True`, the cutoffs of `precision` and `min_digits` refer to the
  1025. total number of digits after the decimal point, including leading
  1026. zeros.
  1027. If `False`, `precision` and `min_digits` refer to the total number of
  1028. significant digits, before or after the decimal point, ignoring leading
  1029. zeros.
  1030. trim : one of 'k', '.', '0', '-', optional
  1031. Controls post-processing trimming of trailing digits, as follows:
  1032. * 'k' : keep trailing zeros, keep decimal point (no trimming)
  1033. * '.' : trim all trailing zeros, leave decimal point
  1034. * '0' : trim all but the zero before the decimal point. Insert the
  1035. zero if it is missing.
  1036. * '-' : trim trailing zeros and any trailing decimal point
  1037. sign : boolean, optional
  1038. Whether to show the sign for positive values.
  1039. pad_left : non-negative integer, optional
  1040. Pad the left side of the string with whitespace until at least that
  1041. many characters are to the left of the decimal point.
  1042. pad_right : non-negative integer, optional
  1043. Pad the right side of the string with whitespace until at least that
  1044. many characters are to the right of the decimal point.
  1045. min_digits : non-negative integer or None, optional
  1046. Minimum number of digits to print. Only has an effect if `unique=True`
  1047. in which case additional digits past those necessary to uniquely
  1048. identify the value may be printed, rounding the last additional digit.
  1049. .. versionadded:: 1.21.0
  1050. Returns
  1051. -------
  1052. rep : string
  1053. The string representation of the floating point value
  1054. See Also
  1055. --------
  1056. format_float_scientific
  1057. Examples
  1058. --------
  1059. >>> import numpy as np
  1060. >>> np.format_float_positional(np.float32(np.pi))
  1061. '3.1415927'
  1062. >>> np.format_float_positional(np.float16(np.pi))
  1063. '3.14'
  1064. >>> np.format_float_positional(np.float16(0.3))
  1065. '0.3'
  1066. >>> np.format_float_positional(np.float16(0.3), unique=False, precision=10)
  1067. '0.3000488281'
  1068. """
  1069. precision = _none_or_positive_arg(precision, 'precision')
  1070. pad_left = _none_or_positive_arg(pad_left, 'pad_left')
  1071. pad_right = _none_or_positive_arg(pad_right, 'pad_right')
  1072. min_digits = _none_or_positive_arg(min_digits, 'min_digits')
  1073. if not fractional and precision == 0:
  1074. raise ValueError("precision must be greater than 0 if "
  1075. "fractional=False")
  1076. if min_digits > 0 and precision > 0 and min_digits > precision:
  1077. raise ValueError("min_digits must be less than or equal to precision")
  1078. return dragon4_positional(x, precision=precision, unique=unique,
  1079. fractional=fractional, trim=trim,
  1080. sign=sign, pad_left=pad_left,
  1081. pad_right=pad_right, min_digits=min_digits)
  1082. class IntegerFormat:
  1083. def __init__(self, data, sign='-'):
  1084. if data.size > 0:
  1085. data_max = np.max(data)
  1086. data_min = np.min(data)
  1087. data_max_str_len = len(str(data_max))
  1088. if sign == ' ' and data_min < 0:
  1089. sign = '-'
  1090. if data_max >= 0 and sign in "+ ":
  1091. data_max_str_len += 1
  1092. max_str_len = max(data_max_str_len,
  1093. len(str(data_min)))
  1094. else:
  1095. max_str_len = 0
  1096. self.format = f'{{:{sign}{max_str_len}d}}'
  1097. def __call__(self, x):
  1098. return self.format.format(x)
  1099. class BoolFormat:
  1100. def __init__(self, data, **kwargs):
  1101. # add an extra space so " True" and "False" have the same length and
  1102. # array elements align nicely when printed, except in 0d arrays
  1103. self.truestr = ' True' if data.shape != () else 'True'
  1104. def __call__(self, x):
  1105. return self.truestr if x else "False"
  1106. class ComplexFloatingFormat:
  1107. """ Formatter for subtypes of np.complexfloating """
  1108. def __init__(self, x, precision, floatmode, suppress_small,
  1109. sign=False, *, legacy=None):
  1110. # for backcompatibility, accept bools
  1111. if isinstance(sign, bool):
  1112. sign = '+' if sign else '-'
  1113. floatmode_real = floatmode_imag = floatmode
  1114. if legacy <= 113:
  1115. floatmode_real = 'maxprec_equal'
  1116. floatmode_imag = 'maxprec'
  1117. self.real_format = FloatingFormat(
  1118. x.real, precision, floatmode_real, suppress_small,
  1119. sign=sign, legacy=legacy
  1120. )
  1121. self.imag_format = FloatingFormat(
  1122. x.imag, precision, floatmode_imag, suppress_small,
  1123. sign='+', legacy=legacy
  1124. )
  1125. def __call__(self, x):
  1126. r = self.real_format(x.real)
  1127. i = self.imag_format(x.imag)
  1128. # add the 'j' before the terminal whitespace in i
  1129. sp = len(i.rstrip())
  1130. i = i[:sp] + 'j' + i[sp:]
  1131. return r + i
  1132. class _TimelikeFormat:
  1133. def __init__(self, data):
  1134. non_nat = data[~isnat(data)]
  1135. if len(non_nat) > 0:
  1136. # Max str length of non-NaT elements
  1137. max_str_len = max(len(self._format_non_nat(np.max(non_nat))),
  1138. len(self._format_non_nat(np.min(non_nat))))
  1139. else:
  1140. max_str_len = 0
  1141. if len(non_nat) < data.size:
  1142. # data contains a NaT
  1143. max_str_len = max(max_str_len, 5)
  1144. self._format = '%{}s'.format(max_str_len)
  1145. self._nat = "'NaT'".rjust(max_str_len)
  1146. def _format_non_nat(self, x):
  1147. # override in subclass
  1148. raise NotImplementedError
  1149. def __call__(self, x):
  1150. if isnat(x):
  1151. return self._nat
  1152. else:
  1153. return self._format % self._format_non_nat(x)
  1154. class DatetimeFormat(_TimelikeFormat):
  1155. def __init__(self, x, unit=None, timezone=None, casting='same_kind',
  1156. legacy=False):
  1157. # Get the unit from the dtype
  1158. if unit is None:
  1159. if x.dtype.kind == 'M':
  1160. unit = datetime_data(x.dtype)[0]
  1161. else:
  1162. unit = 's'
  1163. if timezone is None:
  1164. timezone = 'naive'
  1165. self.timezone = timezone
  1166. self.unit = unit
  1167. self.casting = casting
  1168. self.legacy = legacy
  1169. # must be called after the above are configured
  1170. super().__init__(x)
  1171. def __call__(self, x):
  1172. if self.legacy <= 113:
  1173. return self._format_non_nat(x)
  1174. return super().__call__(x)
  1175. def _format_non_nat(self, x):
  1176. return "'%s'" % datetime_as_string(x,
  1177. unit=self.unit,
  1178. timezone=self.timezone,
  1179. casting=self.casting)
  1180. class TimedeltaFormat(_TimelikeFormat):
  1181. def _format_non_nat(self, x):
  1182. return str(x.astype('i8'))
  1183. class SubArrayFormat:
  1184. def __init__(self, format_function, **options):
  1185. self.format_function = format_function
  1186. self.threshold = options['threshold']
  1187. self.edge_items = options['edgeitems']
  1188. def __call__(self, a):
  1189. self.summary_insert = "..." if a.size > self.threshold else ""
  1190. return self.format_array(a)
  1191. def format_array(self, a):
  1192. if np.ndim(a) == 0:
  1193. return self.format_function(a)
  1194. if self.summary_insert and a.shape[0] > 2*self.edge_items:
  1195. formatted = (
  1196. [self.format_array(a_) for a_ in a[:self.edge_items]]
  1197. + [self.summary_insert]
  1198. + [self.format_array(a_) for a_ in a[-self.edge_items:]]
  1199. )
  1200. else:
  1201. formatted = [self.format_array(a_) for a_ in a]
  1202. return "[" + ", ".join(formatted) + "]"
  1203. class StructuredVoidFormat:
  1204. """
  1205. Formatter for structured np.void objects.
  1206. This does not work on structured alias types like
  1207. np.dtype(('i4', 'i2,i2')), as alias scalars lose their field information,
  1208. and the implementation relies upon np.void.__getitem__.
  1209. """
  1210. def __init__(self, format_functions):
  1211. self.format_functions = format_functions
  1212. @classmethod
  1213. def from_data(cls, data, **options):
  1214. """
  1215. This is a second way to initialize StructuredVoidFormat,
  1216. using the raw data as input. Added to avoid changing
  1217. the signature of __init__.
  1218. """
  1219. format_functions = []
  1220. for field_name in data.dtype.names:
  1221. format_function = _get_format_function(data[field_name], **options)
  1222. if data.dtype[field_name].shape != ():
  1223. format_function = SubArrayFormat(format_function, **options)
  1224. format_functions.append(format_function)
  1225. return cls(format_functions)
  1226. def __call__(self, x):
  1227. str_fields = [
  1228. format_function(field)
  1229. for field, format_function in zip(x, self.format_functions)
  1230. ]
  1231. if len(str_fields) == 1:
  1232. return "({},)".format(str_fields[0])
  1233. else:
  1234. return "({})".format(", ".join(str_fields))
  1235. def _void_scalar_to_string(x, is_repr=True):
  1236. """
  1237. Implements the repr for structured-void scalars. It is called from the
  1238. scalartypes.c.src code, and is placed here because it uses the elementwise
  1239. formatters defined above.
  1240. """
  1241. options = format_options.get().copy()
  1242. if options["legacy"] <= 125:
  1243. return StructuredVoidFormat.from_data(array(x), **options)(x)
  1244. if options.get('formatter') is None:
  1245. options['formatter'] = {}
  1246. options['formatter'].setdefault('float_kind', str)
  1247. val_repr = StructuredVoidFormat.from_data(array(x), **options)(x)
  1248. if not is_repr:
  1249. return val_repr
  1250. cls = type(x)
  1251. cls_fqn = cls.__module__.replace("numpy", "np") + "." + cls.__name__
  1252. void_dtype = np.dtype((np.void, x.dtype))
  1253. return f"{cls_fqn}({val_repr}, dtype={void_dtype!s})"
  1254. _typelessdata = [int_, float64, complex128, _nt.bool]
  1255. def dtype_is_implied(dtype):
  1256. """
  1257. Determine if the given dtype is implied by the representation
  1258. of its values.
  1259. Parameters
  1260. ----------
  1261. dtype : dtype
  1262. Data type
  1263. Returns
  1264. -------
  1265. implied : bool
  1266. True if the dtype is implied by the representation of its values.
  1267. Examples
  1268. --------
  1269. >>> import numpy as np
  1270. >>> np._core.arrayprint.dtype_is_implied(int)
  1271. True
  1272. >>> np.array([1, 2, 3], int)
  1273. array([1, 2, 3])
  1274. >>> np._core.arrayprint.dtype_is_implied(np.int8)
  1275. False
  1276. >>> np.array([1, 2, 3], np.int8)
  1277. array([1, 2, 3], dtype=int8)
  1278. """
  1279. dtype = np.dtype(dtype)
  1280. if format_options.get()['legacy'] <= 113 and dtype.type == np.bool:
  1281. return False
  1282. # not just void types can be structured, and names are not part of the repr
  1283. if dtype.names is not None:
  1284. return False
  1285. # should care about endianness *unless size is 1* (e.g., int8, bool)
  1286. if not dtype.isnative:
  1287. return False
  1288. return dtype.type in _typelessdata
  1289. def dtype_short_repr(dtype):
  1290. """
  1291. Convert a dtype to a short form which evaluates to the same dtype.
  1292. The intent is roughly that the following holds
  1293. >>> from numpy import *
  1294. >>> dt = np.int64([1, 2]).dtype
  1295. >>> assert eval(dtype_short_repr(dt)) == dt
  1296. """
  1297. if type(dtype).__repr__ != np.dtype.__repr__:
  1298. # TODO: Custom repr for user DTypes, logic should likely move.
  1299. return repr(dtype)
  1300. if dtype.names is not None:
  1301. # structured dtypes give a list or tuple repr
  1302. return str(dtype)
  1303. elif issubclass(dtype.type, flexible):
  1304. # handle these separately so they don't give garbage like str256
  1305. return "'%s'" % str(dtype)
  1306. typename = dtype.name
  1307. if not dtype.isnative:
  1308. # deal with cases like dtype('<u2') that are identical to an
  1309. # established dtype (in this case uint16)
  1310. # except that they have a different endianness.
  1311. return "'%s'" % str(dtype)
  1312. # quote typenames which can't be represented as python variable names
  1313. if typename and not (typename[0].isalpha() and typename.isalnum()):
  1314. typename = repr(typename)
  1315. return typename
  1316. def _array_repr_implementation(
  1317. arr, max_line_width=None, precision=None, suppress_small=None,
  1318. array2string=array2string):
  1319. """Internal version of array_repr() that allows overriding array2string."""
  1320. current_options = format_options.get()
  1321. override_repr = current_options["override_repr"]
  1322. if override_repr is not None:
  1323. return override_repr(arr)
  1324. if max_line_width is None:
  1325. max_line_width = current_options['linewidth']
  1326. if type(arr) is not ndarray:
  1327. class_name = type(arr).__name__
  1328. else:
  1329. class_name = "array"
  1330. prefix = class_name + "("
  1331. if (current_options['legacy'] <= 113 and
  1332. arr.shape == () and not arr.dtype.names):
  1333. lst = repr(arr.item())
  1334. else:
  1335. lst = array2string(arr, max_line_width, precision, suppress_small,
  1336. ', ', prefix, suffix=")")
  1337. # Add dtype and shape information if these cannot be inferred from
  1338. # the array string.
  1339. extras = []
  1340. if (arr.size == 0 and arr.shape != (0,)
  1341. or current_options['legacy'] > 210
  1342. and arr.size > current_options['threshold']):
  1343. extras.append(f"shape={arr.shape}")
  1344. if not dtype_is_implied(arr.dtype) or arr.size == 0:
  1345. extras.append(f"dtype={dtype_short_repr(arr.dtype)}")
  1346. if not extras:
  1347. return prefix + lst + ")"
  1348. arr_str = prefix + lst + ","
  1349. extra_str = ", ".join(extras) + ")"
  1350. # compute whether we should put extras on a new line: Do so if adding the
  1351. # extras would extend the last line past max_line_width.
  1352. # Note: This line gives the correct result even when rfind returns -1.
  1353. last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1)
  1354. spacer = " "
  1355. if current_options['legacy'] <= 113:
  1356. if issubclass(arr.dtype.type, flexible):
  1357. spacer = '\n' + ' '*len(prefix)
  1358. elif last_line_len + len(extra_str) + 1 > max_line_width:
  1359. spacer = '\n' + ' '*len(prefix)
  1360. return arr_str + spacer + extra_str
  1361. def _array_repr_dispatcher(
  1362. arr, max_line_width=None, precision=None, suppress_small=None):
  1363. return (arr,)
  1364. @array_function_dispatch(_array_repr_dispatcher, module='numpy')
  1365. def array_repr(arr, max_line_width=None, precision=None, suppress_small=None):
  1366. """
  1367. Return the string representation of an array.
  1368. Parameters
  1369. ----------
  1370. arr : ndarray
  1371. Input array.
  1372. max_line_width : int, optional
  1373. Inserts newlines if text is longer than `max_line_width`.
  1374. Defaults to ``numpy.get_printoptions()['linewidth']``.
  1375. precision : int, optional
  1376. Floating point precision.
  1377. Defaults to ``numpy.get_printoptions()['precision']``.
  1378. suppress_small : bool, optional
  1379. Represent numbers "very close" to zero as zero; default is False.
  1380. Very close is defined by precision: if the precision is 8, e.g.,
  1381. numbers smaller (in absolute value) than 5e-9 are represented as
  1382. zero.
  1383. Defaults to ``numpy.get_printoptions()['suppress']``.
  1384. Returns
  1385. -------
  1386. string : str
  1387. The string representation of an array.
  1388. See Also
  1389. --------
  1390. array_str, array2string, set_printoptions
  1391. Examples
  1392. --------
  1393. >>> import numpy as np
  1394. >>> np.array_repr(np.array([1,2]))
  1395. 'array([1, 2])'
  1396. >>> np.array_repr(np.ma.array([0.]))
  1397. 'MaskedArray([0.])'
  1398. >>> np.array_repr(np.array([], np.int32))
  1399. 'array([], dtype=int32)'
  1400. >>> x = np.array([1e-6, 4e-7, 2, 3])
  1401. >>> np.array_repr(x, precision=6, suppress_small=True)
  1402. 'array([0.000001, 0. , 2. , 3. ])'
  1403. """
  1404. return _array_repr_implementation(
  1405. arr, max_line_width, precision, suppress_small)
  1406. @_recursive_guard()
  1407. def _guarded_repr_or_str(v):
  1408. if isinstance(v, bytes):
  1409. return repr(v)
  1410. return str(v)
  1411. def _array_str_implementation(
  1412. a, max_line_width=None, precision=None, suppress_small=None,
  1413. array2string=array2string):
  1414. """Internal version of array_str() that allows overriding array2string."""
  1415. if (format_options.get()['legacy'] <= 113 and
  1416. a.shape == () and not a.dtype.names):
  1417. return str(a.item())
  1418. # the str of 0d arrays is a special case: It should appear like a scalar,
  1419. # so floats are not truncated by `precision`, and strings are not wrapped
  1420. # in quotes. So we return the str of the scalar value.
  1421. if a.shape == ():
  1422. # obtain a scalar and call str on it, avoiding problems for subclasses
  1423. # for which indexing with () returns a 0d instead of a scalar by using
  1424. # ndarray's getindex. Also guard against recursive 0d object arrays.
  1425. return _guarded_repr_or_str(np.ndarray.__getitem__(a, ()))
  1426. return array2string(a, max_line_width, precision, suppress_small, ' ', "")
  1427. def _array_str_dispatcher(
  1428. a, max_line_width=None, precision=None, suppress_small=None):
  1429. return (a,)
  1430. @array_function_dispatch(_array_str_dispatcher, module='numpy')
  1431. def array_str(a, max_line_width=None, precision=None, suppress_small=None):
  1432. """
  1433. Return a string representation of the data in an array.
  1434. The data in the array is returned as a single string. This function is
  1435. similar to `array_repr`, the difference being that `array_repr` also
  1436. returns information on the kind of array and its data type.
  1437. Parameters
  1438. ----------
  1439. a : ndarray
  1440. Input array.
  1441. max_line_width : int, optional
  1442. Inserts newlines if text is longer than `max_line_width`.
  1443. Defaults to ``numpy.get_printoptions()['linewidth']``.
  1444. precision : int, optional
  1445. Floating point precision.
  1446. Defaults to ``numpy.get_printoptions()['precision']``.
  1447. suppress_small : bool, optional
  1448. Represent numbers "very close" to zero as zero; default is False.
  1449. Very close is defined by precision: if the precision is 8, e.g.,
  1450. numbers smaller (in absolute value) than 5e-9 are represented as
  1451. zero.
  1452. Defaults to ``numpy.get_printoptions()['suppress']``.
  1453. See Also
  1454. --------
  1455. array2string, array_repr, set_printoptions
  1456. Examples
  1457. --------
  1458. >>> import numpy as np
  1459. >>> np.array_str(np.arange(3))
  1460. '[0 1 2]'
  1461. """
  1462. return _array_str_implementation(
  1463. a, max_line_width, precision, suppress_small)
  1464. # needed if __array_function__ is disabled
  1465. _array2string_impl = getattr(array2string, '__wrapped__', array2string)
  1466. _default_array_str = functools.partial(_array_str_implementation,
  1467. array2string=_array2string_impl)
  1468. _default_array_repr = functools.partial(_array_repr_implementation,
  1469. array2string=_array2string_impl)