How to pretty-print a numpy.array without scientific notation and with given precision?

507,368

Solution 1

You can use set_printoptions to set the precision of the output:

import numpy as np
x=np.random.random(10)
print(x)
# [ 0.07837821  0.48002108  0.41274116  0.82993414  0.77610352  0.1023732
#   0.51303098  0.4617183   0.33487207  0.71162095]

np.set_printoptions(precision=3)
print(x)
# [ 0.078  0.48   0.413  0.83   0.776  0.102  0.513  0.462  0.335  0.712]

And suppress suppresses the use of scientific notation for small numbers:

y=np.array([1.5e-10,1.5,1500])
print(y)
# [  1.500e-10   1.500e+00   1.500e+03]
np.set_printoptions(suppress=True)
print(y)
# [    0.      1.5  1500. ]

See the docs for set_printoptions for other options.


To apply print options locally, using NumPy 1.15.0 or later, you could use the numpy.printoptions context manager. For example, inside the with-suite precision=3 and suppress=True are set:

x = np.random.random(10)
with np.printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

But outside the with-suite the print options are back to default settings:

print(x)    
# [ 0.07334334  0.46132615  0.68935231  0.75379645  0.62424021  0.90115836
#   0.04879837  0.58207504  0.55694118  0.34768638]

If you are using an earlier version of NumPy, you can create the context manager yourself. For example,

import numpy as np
import contextlib

@contextlib.contextmanager
def printoptions(*args, **kwargs):
    original = np.get_printoptions()
    np.set_printoptions(*args, **kwargs)
    try:
        yield
    finally: 
        np.set_printoptions(**original)

x = np.random.random(10)
with printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

To prevent zeros from being stripped from the end of floats:

np.set_printoptions now has a formatter parameter which allows you to specify a format function for each type.

np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
print(x)

which prints

[ 0.078  0.480  0.413  0.830  0.776  0.102  0.513  0.462  0.335  0.712]

instead of

[ 0.078  0.48   0.413  0.83   0.776  0.102  0.513  0.462  0.335  0.712]

Solution 2

You can get a subset of the np.set_printoptions functionality from the np.array_str command, which applies only to a single print statement.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.array_str.html

For example:

In [27]: x = np.array([[1.1, 0.9, 1e-6]]*3)

In [28]: print x
[[  1.10000000e+00   9.00000000e-01   1.00000000e-06]
 [  1.10000000e+00   9.00000000e-01   1.00000000e-06]
 [  1.10000000e+00   9.00000000e-01   1.00000000e-06]]

In [29]: print np.array_str(x, precision=2)
[[  1.10e+00   9.00e-01   1.00e-06]
 [  1.10e+00   9.00e-01   1.00e-06]
 [  1.10e+00   9.00e-01   1.00e-06]]

In [30]: print np.array_str(x, precision=2, suppress_small=True)
[[ 1.1  0.9  0. ]
 [ 1.1  0.9  0. ]
 [ 1.1  0.9  0. ]]

Solution 3

Unutbu gave a really complete answer (they got a +1 from me too), but here is a lo-tech alternative:

>>> x=np.random.randn(5)
>>> x
array([ 0.25276524,  2.28334499, -1.88221637,  0.69949927,  1.0285625 ])
>>> ['{:.2f}'.format(i) for i in x]
['0.25', '2.28', '-1.88', '0.70', '1.03']

As a function (using the format() syntax for formatting):

def ndprint(a, format_string ='{0:.2f}'):
    print [format_string.format(v,i) for i,v in enumerate(a)]

Usage:

>>> ndprint(x)
['0.25', '2.28', '-1.88', '0.70', '1.03']

>>> ndprint(x, '{:10.4e}')
['2.5277e-01', '2.2833e+00', '-1.8822e+00', '6.9950e-01', '1.0286e+00']

>>> ndprint(x, '{:.8g}')
['0.25276524', '2.283345', '-1.8822164', '0.69949927', '1.0285625']

The index of the array is accessible in the format string:

>>> ndprint(x, 'Element[{1:d}]={0:.2f}')
['Element[0]=0.25', 'Element[1]=2.28', 'Element[2]=-1.88', 'Element[3]=0.70', 'Element[4]=1.03']

Solution 4

FYI Numpy 1.15 (release date pending) will include a context manager for setting print options locally. This means that the following will work the same as the corresponding example in the accepted answer (by unutbu and Neil G) without having to write your own context manager. E.g., using their example:

x = np.random.random(10)
with np.printoptions(precision=3, suppress=True):
    print(x)
    # [ 0.073  0.461  0.689  0.754  0.624  0.901  0.049  0.582  0.557  0.348]

Solution 5

The gem that makes it all too easy to obtain the result as a string (in today's numpy versions) is hidden in denis answer: np.array2string

>>> import numpy as np
>>> x=np.random.random(10)
>>> np.array2string(x, formatter={'float_kind':'{0:.3f}'.format})
'[0.599 0.847 0.513 0.155 0.844 0.753 0.920 0.797 0.427 0.420]'
Share:
507,368
camillio
Author by

camillio

Updated on July 08, 2022

Comments

  • camillio
    camillio almost 2 years

    I'm curious, whether there is any way to print formatted numpy.arrays, e.g., in a way similar to this:

    x = 1.23456
    print '%.3f' % x
    

    If I want to print the numpy.array of floats, it prints several decimals, often in 'scientific' format, which is rather hard to read even for low-dimensional arrays. However, numpy.array apparently has to be printed as a string, i.e., with %s. Is there a solution for this?

  • bph
    bph about 11 years
    is there a means to apply the formatting to only the specific print statement (as opposed to setting a general output format used by all print statements)?
  • unutbu
    unutbu about 11 years
    @Hiett: There is no NumPy function to set print options for just one print, but you could use a context manager to make something similar. I've edited the post above to show what I mean.
  • Norfeldt
    Norfeldt almost 11 years
    your np.set_printoptions(precision=3) suppress the end zeros.. how do you get them to display like this [ 0.078 0.480 0.413 0.830 0.776 0.102 0.513 0.462 0.335 0.712]?
  • unutbu
    unutbu almost 11 years
    @Norfeldt: I've added a way to do this above.
  • Norfeldt
    Norfeldt almost 11 years
    @unutbu nice! thank you. Is there however a way to avoid the context manager? like np.set_printoptions(precision=3, strip_zeros=False) - I don't feel like using a context every time I need a print :)
  • unutbu
    unutbu almost 11 years
    You could take code inside the first if not strip_zeros statement, and just use that. What I do is put things like the context manager in a utils.py file and import it whenever I need it. So it really does not require much typing to get the functionality you want.
  • jf328
    jf328 over 10 years
    For single use, what about just call set_printoptions(precision = 3, ...) right before your print command and call set_printoptions() ie no argument, return to default, right after your print command
  • Jayesh
    Jayesh about 9 years
    This works great. As a side note, you can also use set_printoptions if you want a string representation and not necessarily use print. You can just call __str__() of the numpy array instance and you will get the formatted string as per the printoptions you set.
  • Yigit Alparslan
    Yigit Alparslan about 4 years
    Creating a decorator might be an overkill every time you want to print. You can use this which is calling str on the array and then printing. suppress_small will suppress the scientific notation. print(np.array_str(X, precision=2, suppress_small=True))
  • Hans
    Hans about 4 years
    This worked for me when passing the array to a matplotlib ylabel, thanks
  • mins
    mins over 3 years
    Likely the most simple and efficient option as it doesn't introduce a permanent change in printoptions, nor requires a costly loop or a with construction. The possibility to format elements should be integrated into numpy directly (can't understand why it is not the case).
  • Brandon Rhodes
    Brandon Rhodes over 3 years
    But it does mean creating a second copy of the array each time you want to print it out, which might dissuade some use cases.