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

## Question:

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?

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]
``````

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

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']
``````

Years later, another one is below. But for everyday use I just

``````np.set_printoptions( threshold=20, edgeitems=10, linewidth=140,
formatter = dict( float = lambda x: "%.3g" % x ))  # float arrays %.3g
``````

``````''' printf( "... %.3g ... %.1f  ...", arg, arg ... ) for numpy arrays too

Example:
printf( """ x: %.3g   A: %.1f   s: %s   B: %s """,
x,        A,        "str",  B )

If `x` and `A` are numbers, this is like `"format" % (x, A, "str", B)` in python.
If they're numpy arrays, each element is printed in its own format:
`x`: e.g. [ 1.23 1.23e-6 ... ]  3 digits
`A`: [ [ 1 digit after the decimal point ... ] ... ]
with the current `np.set_printoptions()`. For example, with
np.set_printoptions( threshold=100, edgeitems=3, suppress=True )
only the edges of big `x` and `A` are printed.
`B` is printed as `str(B)`, for any `B` -- a number, a list, a numpy object ...

`printf()` tries to handle too few or too many arguments sensibly,
but this is iffy and subject to change.

How it works:
numpy has a function `np.array2string( A, "%.3g" )` (simplifying a bit).
`printf()` splits the format string, and for format / arg pairs
format: % d e f g
arg: try `np.asanyarray()`
-->  %s  np.array2string( arg, format )
Other formats and non-ndarray args are left alone, formatted as usual.

Notes:

`printf( ... end= file= )` are passed on to the python `print()` function.

Only formats `% [optional width . precision] d e f g` are implemented,
not `%(varname)format` .

%d truncates floats, e.g. 0.9 and -0.9 to 0; %.0f rounds, 0.9 to 1 .
%g is the same as %.6g, 6 digits.
%% is a single "%" character.

The function `sprintf()` returns a long string. For example,
title = sprintf( "%s  m %g  n %g  X %.3g",
__file__, m, n, X )
print( title )
...
pl.title( title )

Module globals:
_fmt = "%.3g"  # default for extra args
_squeeze = np.squeeze  # (n,1) (1,n) -> (n,) print in 1 line not n

http://docs.scipy.org/doc/numpy/reference/generated/numpy.set_printoptions.html
http://docs.python.org/2.7/library/stdtypes.html#string-formatting

'''
# http://stackoverflow.com/questions/2891790/pretty-printing-of-numpy-array

#...............................................................................
from __future__ import division, print_function
import re
import numpy as np

__version__ = "2014-02-03 feb denis"

_splitformat = re.compile( r'''(
%
(?<! %% )  # not %%
-? [ d . ]*  # optional width.precision
w
)''', re.X )
# ... %3.0f  ... %g  ... %-10s ...
# -> ['...' '%3.0f' '...' '%g' '...' '%-10s' '...']
# odd len, first or last may be ""

_fmt = "%.3g"  # default for extra args
_squeeze = np.squeeze  # (n,1) (1,n) -> (n,) print in 1 line not n

#...............................................................................
def printf( format, *args, **kwargs ):
print( sprintf( format, *args ), **kwargs )  # end= file=

printf.__doc__ = __doc__

def sprintf( format, *args ):
""" sprintf( "text %.3g text %4.1f ... %s ... ", numpy arrays or ... )
%[defg] array -> np.array2string( formatter= )
"""
args = list(args)
if not isinstance( format, basestring ):
args = [format] + args
format = ""

tf = _splitformat.split( format )  # [ text %e text %f ... ]
nfmt = len(tf) // 2
nargs = len(args)
if nargs < nfmt:
args += (nfmt - nargs) * ["?arg?"]
elif nargs > nfmt:
tf += (nargs - nfmt) * [_fmt, " "]  # default _fmt

for j, arg in enumerate( args ):
fmt = tf[ 2*j + 1 ]
if arg is None
or isinstance( arg, basestring )
or (hasattr( arg, "__iter__" ) and len(arg) == 0):
tf[ 2*j + 1 ] = "%s"  # %f -> %s, not error
continue
args[j], isarray = _tonumpyarray(arg)
if isarray  and fmt[-1] in "defgEFG":
tf[ 2*j + 1 ] = "%s"
fmtfunc = (lambda x: fmt % x)
formatter = dict( float_kind=fmtfunc, int=fmtfunc )
args[j] = np.array2string( args[j], formatter=formatter )
try:
return "".join(tf) % tuple(args)
except TypeError:  # shouldn't happen
print( "error: tf %s  types %s" % (tf, map( type, args )))
raise

def _tonumpyarray( a ):
""" a, isarray = _tonumpyarray( a )
->  scalar, False
np.asanyarray(a), float or int
a, False
"""
a = getattr( a, "value", a )  # cvxpy
if np.isscalar(a):
return a, False
if hasattr( a, "__iter__" )  and len(a) == 0:
return a, False
try:
# map .value ?
a = np.asanyarray( a )
except ValueError:
return a, False
if hasattr( a, "dtype" )  and a.dtype.kind in "fi":  # complex ?
if callable( _squeeze ):
a = _squeeze( a )  # np.squeeze
return a, True
else:
return a, False

#...............................................................................
if __name__ == "__main__":
import sys

n = 5
seed = 0
# run this.py n= ...  in sh or ipython
for arg in sys.argv[1:]:
exec( arg )
np.set_printoptions( 1, threshold=4, edgeitems=2, linewidth=80, suppress=True )
np.random.seed(seed)

A = np.random.exponential( size=(n,n) ) ** 10
x = A[0]

printf( "x: %.3g  nA: %.1f  ns: %s  nB: %s ",
x,         A,         "str",   A )
printf( "x %%d: %d", x )
printf( "x %%.0f: %.0f", x )
printf( "x %%.1e: %.1e", x )
printf( "x %%g: %g", x )
printf( "x %%s uses np printoptions: %s", x )

printf( "x with default _fmt: ", x )
printf( "no args" )
printf( "too few args: %g %g", x )
printf( x )
printf( x, x )
printf( None )
printf( "[]:", [] )
printf( "[3]:", [3] )
printf( np.array( [] ))
printf( [[]] )  # squeeze
``````

And here is what I use, and it’s pretty uncomplicated:

``````print(np.vectorize("%.2f".__mod__)(sparse))
``````

`numpy.char.mod` may also be useful, depending on the details of your application e.g.:`numpy.char.mod('Value=%4.2f', numpy.arange(5, 10, 0.1))` will return a string array with elements “Value=5.00”, “Value=5.10” etc. (as a somewhat contrived example).

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. ]]
``````

I often want different columns to have different formats. Here is how I print a simple 2D array using some variety in the formatting by converting (slices of) my NumPy array to a tuple:

``````import numpy as np
dat = np.random.random((10,11))*100  # Array of random values between 0 and 100
print(dat)                           # Lines get truncated and are hard to read
for i in range(10):
print((4*"%6.2f"+7*"%9.4f") % tuple(dat[i,:]))
``````

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]'
``````

Yet another option is to use the `decimal` module:

``````import numpy as np
from decimal import *

arr = np.array([  56.83,  385.3 ,    6.65,  126.63,   85.76,  192.72,  112.81, 10.55])
arr2 = [str(Decimal(i).quantize(Decimal('.01'))) for i in arr]

# ['56.83', '385.30', '6.65', '126.63', '85.76', '192.72', '112.81', '10.55']
``````

Was surprised to not see `around` method mentioned – means no messing with print options.

``````import numpy as np

x = np.random.random([5,5])
print(np.around(x,decimals=3))

Output:
[[0.475 0.239 0.183 0.991 0.171]
[0.231 0.188 0.235 0.335 0.049]
[0.87  0.212 0.219 0.9   0.3  ]
[0.628 0.791 0.409 0.5   0.319]
[0.614 0.84  0.812 0.4   0.307]]
``````

The numpy arrays have the method `round(precision)` which returns a new numpy array with elements rounded accordingly.

``````import numpy as np

x = np.random.random([5,5])
print(x.round(3))
``````

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]
``````

I find that the usual float format {:9.5f} works properly — suppressing small-value e-notations — when displaying a list or an array using a loop. But that format sometimes fails to suppress its e-notation when a formatter has several items in a single print statement. For example:

``````import numpy as np
np.set_printoptions(suppress=True)
a3 = 4E-3
a4 = 4E-4
a5 = 4E-5
a6 = 4E-6
a7 = 4E-7
a8 = 4E-8
#--first, display separate numbers-----------
print('Case 3:  a3, a4, a5:             {:9.5f}{:9.5f}{:9.5f}'.format(a3,a4,a5))
print('Case 4:  a3, a4, a5, a6:         {:9.5f}{:9.5f}{:9.5f}{:9.5}'.format(a3,a4,a5,a6))
print('Case 5:  a3, a4, a5, a6, a7:     {:9.5f}{:9.5f}{:9.5f}{:9.5}{:9.5f}'.format(a3,a4,a5,a6,a7))
print('Case 6:  a3, a4, a5, a6, a7, a8: {:9.5f}{:9.5f}{:9.5f}{:9.5f}{:9.5}{:9.5f}'.format(a3,a4,a5,a6,a7,a8))
#---second, display a list using a loop----------
myList = [a3,a4,a5,a6,a7,a8]
print('List 6:  a3, a4, a5, a6, a7, a8: ', end='')
for x in myList:
print('{:9.5f}'.format(x), end='')
print()
#---third, display a numpy array using a loop------------
myArray = np.array(myList)
print('Array 6: a3, a4, a5, a6, a7, a8: ', end='')
for x in myArray:
print('{:9.5f}'.format(x), end='')
print()
``````

My results show the bug in cases 4, 5, and 6:

``````Case 3:  a3, a4, a5:               0.00400  0.00040  0.00004
Case 4:  a3, a4, a5, a6:           0.00400  0.00040  0.00004    4e-06
Case 5:  a3, a4, a5, a6, a7:       0.00400  0.00040  0.00004    4e-06  0.00000
Case 6:  a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000    4e-07  0.00000
List 6:  a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000  0.00000  0.00000
Array 6: a3, a4, a5, a6, a7, a8:   0.00400  0.00040  0.00004  0.00000  0.00000  0.00000
``````

I have no explanation for this, and therefore I always use a loop for floating output of multiple values.

I use

``````def np_print(array,fmt="10.5f"):
print (array.size*("{:"+fmt+"}")).format(*array)
``````

It’s not difficult to modify it for multi-dimensional arrays.

Categories: questions
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.