Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fbffb8c

Browse files
authored
Merge pull request #27482 from mhvk/arrayprint-shape-for-summarized
Show shape any time it cannot be inferred in repr
2 parents 6860d85 + 3c6d763 commit fbffb8c

File tree

3 files changed

+94
-59
lines changed

3 files changed

+94
-59
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
* The ``repr`` of arrays large enough to be summarized (i.e., where elements
2+
are replaced with ``...``) now includes the ``shape`` of the array, similar
3+
to what already was the case for arrays with zero size and non-obvious
4+
shape. With this change, the shape is always given when it cannot be
5+
inferred from the values. Note that while written as ``shape=...``, this
6+
argument cannot actually be passed in to the ``np.array`` constructor. If
7+
you encounter problems, e.g., due to failing doctests, you can use the print
8+
option ``legacy=2.1`` to get the old behaviour.

numpy/_core/arrayprint.py

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,14 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
8383
options['legacy'] = 121
8484
elif legacy == '1.25':
8585
options['legacy'] = 125
86+
elif legacy == '2.1':
87+
options['legacy'] = 201
8688
elif legacy is None:
8789
pass # OK, do nothing.
8890
else:
8991
warnings.warn(
9092
"legacy printing option can currently only be '1.13', '1.21', "
91-
"'1.25', or `False`", stacklevel=3)
93+
"'1.25', '2.1, or `False`", stacklevel=3)
9294

9395
if threshold is not None:
9496
# forbid the bad threshold arg suggested by stack overflow, gh-12351
@@ -214,13 +216,16 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
214216
that numeric scalars are printed without their type information, e.g.
215217
as ``3.0`` rather than ``np.float64(3.0)``.
216218
219+
If set to ``'2.1'``, shape information is not given when arrays are
220+
summarized (i.e., multiple elements replaced with ``...``).
221+
217222
If set to `False`, disables legacy mode.
218223
219224
Unrecognized strings will be ignored with a warning for forward
220225
compatibility.
221226
222227
.. versionchanged:: 1.22.0
223-
.. versionchanged:: 2.0
228+
.. versionchanged:: 2.2
224229
225230
override_repr: callable, optional
226231
If set a passed function will be used for generating arrays' repr.
@@ -249,7 +254,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
249254
250255
>>> np.set_printoptions(threshold=5)
251256
>>> np.arange(10)
252-
array([0, 1, 2, ..., 7, 8, 9])
257+
array([0, 1, 2, ..., 7, 8, 9], shape=(10,))
253258
254259
Small results can be suppressed:
255260
@@ -282,7 +287,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
282287
283288
>>> with np.printoptions(precision=2, suppress=True, threshold=5):
284289
... np.linspace(0, 10, 10)
285-
array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ])
290+
array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ], shape=(10,))
286291
287292
"""
288293
_set_printoptions(precision, threshold, edgeitems, linewidth, suppress,
@@ -1578,39 +1583,41 @@ def _array_repr_implementation(
15781583
else:
15791584
class_name = "array"
15801585

1581-
skipdtype = dtype_is_implied(arr.dtype) and arr.size > 0
1582-
15831586
prefix = class_name + "("
1584-
suffix = ")" if skipdtype else ","
1585-
15861587
if (current_options['legacy'] <= 113 and
15871588
arr.shape == () and not arr.dtype.names):
15881589
lst = repr(arr.item())
1589-
elif arr.size > 0 or arr.shape == (0,):
1590+
else:
15901591
lst = array2string(arr, max_line_width, precision, suppress_small,
1591-
', ', prefix, suffix=suffix)
1592-
else: # show zero-length shape unless it is (0,)
1593-
lst = "[], shape=%s" % (repr(arr.shape),)
1594-
1595-
arr_str = prefix + lst + suffix
1596-
1597-
if skipdtype:
1598-
return arr_str
1599-
1600-
dtype_str = "dtype={})".format(dtype_short_repr(arr.dtype))
1601-
1602-
# compute whether we should put dtype on a new line: Do so if adding the
1603-
# dtype would extend the last line past max_line_width.
1592+
', ', prefix, suffix=")")
1593+
1594+
# Add dtype and shape information if these cannot be inferred from
1595+
# the array string.
1596+
extras = []
1597+
if (arr.size == 0 and arr.shape != (0,)
1598+
or current_options['legacy'] > 210
1599+
and arr.size > current_options['threshold']):
1600+
extras.append(f"shape={arr.shape}")
1601+
if not dtype_is_implied(arr.dtype) or arr.size == 0:
1602+
extras.append(f"dtype={dtype_short_repr(arr.dtype)}")
1603+
1604+
if not extras:
1605+
return prefix + lst + ")"
1606+
1607+
arr_str = prefix + lst + ","
1608+
extra_str = ", ".join(extras) + ")"
1609+
# compute whether we should put extras on a new line: Do so if adding the
1610+
# extras would extend the last line past max_line_width.
16041611
# Note: This line gives the correct result even when rfind returns -1.
16051612
last_line_len = len(arr_str) - (arr_str.rfind('\n') + 1)
16061613
spacer = " "
16071614
if current_options['legacy'] <= 113:
16081615
if issubclass(arr.dtype.type, flexible):
1609-
spacer = '\n' + ' '*len(class_name + "(")
1610-
elif last_line_len + len(dtype_str) + 1 > max_line_width:
1611-
spacer = '\n' + ' '*len(class_name + "(")
1616+
spacer = '\n' + ' '*len(prefix)
1617+
elif last_line_len + len(extra_str) + 1 > max_line_width:
1618+
spacer = '\n' + ' '*len(prefix)
16121619

1613-
return arr_str + spacer + dtype_str
1620+
return arr_str + spacer + extra_str
16141621

16151622

16161623
def _array_repr_dispatcher(

numpy/_core/tests/test_arrayprint.py

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,13 @@ def test_summarize_1d(self):
346346
assert_equal(str(A), strA)
347347

348348
reprA = 'array([ 0, 1, 2, ..., 998, 999, 1000])'
349-
assert_equal(repr(A), reprA)
349+
try:
350+
np.set_printoptions(legacy='2.1')
351+
assert_equal(repr(A), reprA)
352+
finally:
353+
np.set_printoptions(legacy=False)
354+
355+
assert_equal(repr(A), reprA.replace(')', ', shape=(1001,))'))
350356

351357
def test_summarize_2d(self):
352358
A = np.arange(1002).reshape(2, 501)
@@ -356,6 +362,23 @@ def test_summarize_2d(self):
356362

357363
reprA = 'array([[ 0, 1, 2, ..., 498, 499, 500],\n' \
358364
' [ 501, 502, 503, ..., 999, 1000, 1001]])'
365+
try:
366+
np.set_printoptions(legacy='2.1')
367+
assert_equal(repr(A), reprA)
368+
finally:
369+
np.set_printoptions(legacy=False)
370+
371+
assert_equal(repr(A), reprA.replace(')', ', shape=(2, 501))'))
372+
373+
def test_summarize_2d_dtype(self):
374+
A = np.arange(1002, dtype='i2').reshape(2, 501)
375+
strA = '[[ 0 1 2 ... 498 499 500]\n' \
376+
' [ 501 502 503 ... 999 1000 1001]]'
377+
assert_equal(str(A), strA)
378+
379+
reprA = ('array([[ 0, 1, 2, ..., 498, 499, 500],\n'
380+
' [ 501, 502, 503, ..., 999, 1000, 1001]],\n'
381+
' shape=(2, 501), dtype=int16)')
359382
assert_equal(repr(A), reprA)
360383

361384
def test_summarize_structure(self):
@@ -1040,7 +1063,7 @@ def test_edgeitems(self):
10401063
10411064
[[18, ..., 20],
10421065
...,
1043-
[24, ..., 26]]])""")
1066+
[24, ..., 26]]], shape=(3, 3, 3))""")
10441067
)
10451068

10461069
b = np.zeros((3, 3, 1, 1))
@@ -1061,40 +1084,37 @@ def test_edgeitems(self):
10611084
10621085
...,
10631086
1064-
[[0.]]]])""")
1087+
[[0.]]]], shape=(3, 3, 1, 1))""")
10651088
)
10661089

10671090
# 1.13 had extra trailing spaces, and was missing newlines
1068-
np.set_printoptions(legacy='1.13')
1069-
1070-
assert_equal(
1071-
repr(a),
1072-
textwrap.dedent("""\
1073-
array([[[ 0, ..., 2],
1074-
...,
1075-
[ 6, ..., 8]],
1076-
1077-
...,
1078-
[[18, ..., 20],
1079-
...,
1080-
[24, ..., 26]]])""")
1081-
)
1082-
1083-
assert_equal(
1084-
repr(b),
1085-
textwrap.dedent("""\
1086-
array([[[[ 0.]],
1087-
1088-
...,
1089-
[[ 0.]]],
1090-
1091-
1092-
...,
1093-
[[[ 0.]],
1094-
1095-
...,
1096-
[[ 0.]]]])""")
1097-
)
1091+
try:
1092+
np.set_printoptions(legacy='1.13')
1093+
assert_equal(repr(a), (
1094+
"array([[[ 0, ..., 2],\n"
1095+
" ..., \n"
1096+
" [ 6, ..., 8]],\n"
1097+
"\n"
1098+
" ..., \n"
1099+
" [[18, ..., 20],\n"
1100+
" ..., \n"
1101+
" [24, ..., 26]]])")
1102+
)
1103+
assert_equal(repr(b), (
1104+
"array([[[[ 0.]],\n"
1105+
"\n"
1106+
" ..., \n"
1107+
" [[ 0.]]],\n"
1108+
"\n"
1109+
"\n"
1110+
" ..., \n"
1111+
" [[[ 0.]],\n"
1112+
"\n"
1113+
" ..., \n"
1114+
" [[ 0.]]]])")
1115+
)
1116+
finally:
1117+
np.set_printoptions(legacy=False)
10981118

10991119
def test_edgeitems_structured(self):
11001120
np.set_printoptions(edgeitems=1, threshold=1)

0 commit comments

Comments
 (0)