Skip to content

Navigation Menu

Sign in
Appearance settings

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

Provide feedback

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

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Show shape any time it cannot be inferred in repr #27482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
ENH: include shape in repr also for summarized arrays
So that it is always there when the shape cannot be inferred from list
  • Loading branch information
mhvk committed Nov 4, 2024
commit 3c6d76331d81966830f79b54adadb09dc942ad65
8 changes: 8 additions & 0 deletions 8 doc/release/upcoming_changes/27482.change.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* The ``repr`` of arrays large enough to be summarized (i.e., where elements
are replaced with ``...``) now includes the ``shape`` of the array, similar
to what already was the case for arrays with zero size and non-obvious
shape. With this change, the shape is always given when it cannot be
inferred from the values. Note that while written as ``shape=...``, this
argument cannot actually be passed in to the ``np.array`` constructor. If
you encounter problems, e.g., due to failing doctests, you can use the print
option ``legacy=2.1`` to get the old behaviour.
21 changes: 15 additions & 6 deletions 21 numpy/_core/arrayprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,14 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
options['legacy'] = 121
elif legacy == '1.25':
options['legacy'] = 125
elif legacy == '2.1':
options['legacy'] = 201
elif legacy is None:
pass # OK, do nothing.
else:
warnings.warn(
"legacy printing option can currently only be '1.13', '1.21', "
"'1.25', or `False`", stacklevel=3)
"'1.25', '2.1, or `False`", stacklevel=3)

if threshold is not None:
# forbid the bad threshold arg suggested by stack overflow, gh-12351
Expand Down Expand Up @@ -214,13 +216,16 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
that numeric scalars are printed without their type information, e.g.
as ``3.0`` rather than ``np.float64(3.0)``.

If set to ``'2.1'``, shape information is not given when arrays are
summarized (i.e., multiple elements replaced with ``...``).

If set to `False`, disables legacy mode.

Unrecognized strings will be ignored with a warning for forward
compatibility.

.. versionchanged:: 1.22.0
.. versionchanged:: 2.0
.. versionchanged:: 2.2

override_repr: callable, optional
If set a passed function will be used for generating arrays' repr.
Expand Down Expand Up @@ -249,7 +254,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,

>>> np.set_printoptions(threshold=5)
>>> np.arange(10)
array([0, 1, 2, ..., 7, 8, 9])
array([0, 1, 2, ..., 7, 8, 9], shape=(10,))

Small results can be suppressed:

Expand Down Expand Up @@ -282,7 +287,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,

>>> with np.printoptions(precision=2, suppress=True, threshold=5):
... np.linspace(0, 10, 10)
array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ])
array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ], shape=(10,))

"""
_set_printoptions(precision, threshold, edgeitems, linewidth, suppress,
Expand Down Expand Up @@ -1586,11 +1591,15 @@ def _array_repr_implementation(
lst = array2string(arr, max_line_width, precision, suppress_small,
', ', prefix, suffix=")")

# Add dtype and shape information if these cannot be inferred from
# the array string.
extras = []
if (arr.size == 0 and arr.shape != (0,)
or current_options['legacy'] > 210
and arr.size > current_options['threshold']):
extras.append(f"shape={arr.shape}")
if not dtype_is_implied(arr.dtype) or arr.size == 0:
extras.append(f"dtype={dtype_short_repr(arr.dtype)}")
if arr.size == 0 and arr.shape != (0,):
extras.append(f"{shape=}")

if not extras:
return prefix + lst + ")"
Expand Down
86 changes: 53 additions & 33 deletions 86 numpy/_core/tests/test_arrayprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,13 @@ def test_summarize_1d(self):
assert_equal(str(A), strA)

reprA = 'array([ 0, 1, 2, ..., 998, 999, 1000])'
assert_equal(repr(A), reprA)
try:
np.set_printoptions(legacy='2.1')
assert_equal(repr(A), reprA)
finally:
np.set_printoptions(legacy=False)

assert_equal(repr(A), reprA.replace(')', ', shape=(1001,))'))

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

reprA = 'array([[ 0, 1, 2, ..., 498, 499, 500],\n' \
' [ 501, 502, 503, ..., 999, 1000, 1001]])'
try:
np.set_printoptions(legacy='2.1')
assert_equal(repr(A), reprA)
finally:
np.set_printoptions(legacy=False)

assert_equal(repr(A), reprA.replace(')', ', shape=(2, 501))'))

def test_summarize_2d_dtype(self):
A = np.arange(1002, dtype='i2').reshape(2, 501)
strA = '[[ 0 1 2 ... 498 499 500]\n' \
' [ 501 502 503 ... 999 1000 1001]]'
assert_equal(str(A), strA)

reprA = ('array([[ 0, 1, 2, ..., 498, 499, 500],\n'
' [ 501, 502, 503, ..., 999, 1000, 1001]],\n'
' shape=(2, 501), dtype=int16)')
assert_equal(repr(A), reprA)

def test_summarize_structure(self):
Expand Down Expand Up @@ -1040,7 +1063,7 @@ def test_edgeitems(self):

[[18, ..., 20],
...,
[24, ..., 26]]])""")
[24, ..., 26]]], shape=(3, 3, 3))""")
)

b = np.zeros((3, 3, 1, 1))
Expand All @@ -1061,40 +1084,37 @@ def test_edgeitems(self):

...,

[[0.]]]])""")
[[0.]]]], shape=(3, 3, 1, 1))""")
)

# 1.13 had extra trailing spaces, and was missing newlines
np.set_printoptions(legacy='1.13')

assert_equal(
repr(a),
textwrap.dedent("""\
array([[[ 0, ..., 2],
...,
[ 6, ..., 8]],

...,
[[18, ..., 20],
...,
[24, ..., 26]]])""")
)

assert_equal(
repr(b),
textwrap.dedent("""\
array([[[[ 0.]],

...,
[[ 0.]]],


...,
[[[ 0.]],

...,
[[ 0.]]]])""")
)
try:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change does two things: correctly put the printoptions setting inside a try/finally, and ensure that there are never any spaces at the end of a line (my editor removed those, thus causing the tests to fail).

np.set_printoptions(legacy='1.13')
assert_equal(repr(a), (
"array([[[ 0, ..., 2],\n"
" ..., \n"
" [ 6, ..., 8]],\n"
"\n"
" ..., \n"
" [[18, ..., 20],\n"
" ..., \n"
" [24, ..., 26]]])")
)
assert_equal(repr(b), (
"array([[[[ 0.]],\n"
"\n"
" ..., \n"
" [[ 0.]]],\n"
"\n"
"\n"
" ..., \n"
" [[[ 0.]],\n"
"\n"
" ..., \n"
" [[ 0.]]]])")
)
finally:
np.set_printoptions(legacy=False)

def test_edgeitems_structured(self):
np.set_printoptions(edgeitems=1, threshold=1)
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.