如何漂亮打印numpy.array没有科学记数法和给定的精度?
我很好奇,是否有任何方式打印格式numpy.arrays,例如,类似于这样的:
x = 1.23456 print '%.3f' % x
如果我想打印浮点数的numpy.array,它打印几个小数,通常是'科学'的格式,这是很难读,即使是低维数组。 但是,numpy.array显然必须作为string打印,即%s。 有没有解决这个问题的方法?
您可以使用set_printoptions
来设置输出的精度:
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]
并suppress
压制小数字使用科学记数法:
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. ]
有关其他选项,请参阅set_printoptions的文档 。
要在本地应用打印选项 ,您可以使用上下文pipe理器 :
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)
例如,在with-suite
precision=3
和suppress=True
中设置:
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]
但是在with-suite
外部,打印选项已恢复为默认设置:
print(x) # [ 0.07334334 0.46132615 0.68935231 0.75379645 0.62424021 0.90115836 # 0.04879837 0.58207504 0.55694118 0.34768638]
为了防止从浮游物的末端剥离零点:
np.set_printoptions
现在有一个formatter
参数,它允许你为每个types指定一个格式化函数。
np.set_printoptions(formatter={'float': '{: 0.3f}'.format}) print(x)
打印
[ 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给出了一个非常完整的答案(他们也得到了我的+1),但是这里是一个低技术的select:
>>> 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']
作为一个函数(使用format()
语法进行格式化):
def ndprint(a, format_string ='{0:.2f}'): print [format_string.format(v,i) for i,v in enumerate(a)]
用法:
>>> 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']
数组的索引可以用格式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']
您可以从np.array_str
命令获取np.set_printoptions
function的一个子集,该命令仅适用于单个打印语句。
http://docs.scipy.org/doc/numpy/reference/generated/numpy.array_str.html
例如:
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. ]]
使得它很容易获得结果作为一个string(在今天的numpy版本)的np.array2string
隐藏在denis中答案: 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]'
下面是我使用的,它很简单:
print(np.vectorize("%.2f".__mod__)(sparse))
多年后,另一个在下面。 但是对于日常使用我只是
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`: eg [ 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: % defg 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] defg` are implemented, not `%(varname)format` . %d truncates floats, eg 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( "%sm %gn %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'''( % (?<! %% ) # 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
我经常想要不同的列有不同的格式。 下面是我如何打印一个简单的二维数组,通过转换(切片)我的NumPy数组到一个元组格式的格式:
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,:]))
numpy.char.mod
也可能是有用的,这取决于你的应用程序的细节,例如: numpy.char.mod('Value=%4.2f', numpy.arange(5, 10, 0.1))
将返回一个string数组元素“价值= 5.00”,“价值= 5.10”等(作为一个有点人为的例子)。