python - multiplicar - numpy tutorial español pdf
¿Cómo hacer una impresión bonita de un numpy.array sin notación científica y con una precisión dada? (14)
A menudo quiero que diferentes columnas tengan diferentes formatos. Aquí es cómo imprimo una matriz 2D simple utilizando cierta variedad en el formato al convertir (porciones de) mi matriz NumPy en una tupla:
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,:]))
Tengo curiosidad por saber si hay alguna forma de imprimir numpy.arrays formateados, por ejemplo, de forma similar a esto:
x = 1.23456
print ''%.3f'' % x
Si quiero imprimir el número de una variedad de flotadores, imprime varios decimales, a menudo en formato ''científico'', que es bastante difícil de leer incluso para matrices de baja dimensión. Sin embargo, numpy.array aparentemente debe imprimirse como una cadena, es decir, con% s. ¿Hay alguna solución para este propósito?
Años después, otro está abajo. Pero para el uso diario acabo
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://.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
Encuentro que el formato flotante habitual {: 9.5f} funciona correctamente, suprimiendo las notaciones electrónicas de pequeño valor, cuando se muestra una lista o una matriz utilizando un bucle. Pero ese formato a veces no puede suprimir su notación electrónica cuando un formateador tiene varios elementos en una sola declaración de impresión. Por ejemplo:
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()
Mis resultados muestran el error en los casos 4, 5 y 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
No tengo una explicación para esto y, por lo tanto, siempre uso un bucle para la salida flotante de múltiples valores.
FYI Numpy 1.15 (fecha de lanzamiento pendiente) incluirá un administrador de contexto para configurar las opciones de impresión localmente . Esto significa que lo siguiente funcionará de la misma manera que el ejemplo correspondiente en la respuesta aceptada (por unutbu y Neil G) sin tener que escribir su propio administrador de contexto. Ej., Usando su ejemplo:
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]
La gema que hace que sea muy fácil obtener el resultado como una cadena (en las versiones de hoy en día) está oculta en la respuesta 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]''
Las matrices numpy tienen el método round(precision)
que devuelve una nueva matriz numpy con elementos redondeados en consecuencia.
import numpy as np
x = np.random.random([5,5])
print(x.round(3))
Me sorprendió que no viera el método mencionado, lo que significa que no tendrá problemas con las opciones de impresión.
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]]
Otra opción más es usar el módulo decimal
:
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'']
Puede obtener un subconjunto de la funcionalidad np.array_str
comando np.array_str
, que se aplica solo a una sola declaración de impresión.
http://docs.scipy.org/doc/numpy/reference/generated/numpy.array_str.html
Por ejemplo:
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. ]]
Puede usar set_printoptions
para establecer la precisión de la salida:
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]
Y suppress
el uso de la notación científica para números pequeños:
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. ]
Vea los documentos para set_printoptions para otras opciones.
Para aplicar las opciones de impresión localmente , utilizando NumPy 1.15.0 o posterior, puede usar el numpy.printoptions contexto numpy.printoptions . Por ejemplo, dentro de la precision=3
with-suite
precision=3
y suppress=True
se establecen:
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]
Pero fuera de with-suite
las opciones de impresión vuelven a la configuración predeterminada:
print(x)
# [ 0.07334334 0.46132615 0.68935231 0.75379645 0.62424021 0.90115836
# 0.04879837 0.58207504 0.55694118 0.34768638]
Si está utilizando una versión anterior de NumPy, puede crear usted mismo el administrador de contexto. Por ejemplo,
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]
Para evitar que los ceros se eliminen del final de las flotaciones:
np.set_printoptions
ahora tiene un parámetro de formatter
que le permite especificar una función de formato para cada tipo.
np.set_printoptions(formatter={''float'': ''{: 0.3f}''.format})
print(x)
que imprime
[ 0.078 0.480 0.413 0.830 0.776 0.102 0.513 0.462 0.335 0.712]
en lugar de
[ 0.078 0.48 0.413 0.83 0.776 0.102 0.513 0.462 0.335 0.712]
Unutbu dio una respuesta realmente completa (también obtuvieron un +1 de mi parte), pero aquí hay una alternativa de baja tecnología:
>>> 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'']
Como una función (usando la sintaxis format()
para formatear):
def ndprint(a, format_string =''{0:.2f}''):
print [format_string.format(v,i) for i,v in enumerate(a)]
Uso:
>>> 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'']
El índice de la matriz es accesible en la cadena de formato:
>>> 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'']
Y aquí está lo que uso, y es bastante sencillo:
print(np.vectorize("%.2f".__mod__)(sparse))
yo suelo
def np_print(array,fmt="10.5f"):
print (array.size*("{:"+fmt+"}")).format(*array)
No es difícil modificarlo para matrices multidimensionales.
numpy.char.mod
también puede ser útil, dependiendo de los detalles de su aplicación, por ejemplo: numpy.char.mod(''Value=%4.2f'', numpy.arange(5, 10, 0.1))
devolverá una matriz de cadena con los elementos "Valor = 5.00", "Valor = 5.10", etc. (como un ejemplo un tanto artificial).