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

后端 未结 14 2366
臣服心动
臣服心动 2020-11-22 04:28

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
         


        
14条回答
  •  深忆病人
    2020-11-22 04:33

    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
    
    See also:
    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'''(
        %
        (? ['...' '%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
    

提交回复
热议问题