Dar formato / suprimir la notación científica de los resultados de agregación de Python Pandas

206

¿Cómo se puede modificar el formato para la salida de una operación groupby en pandas que produce notación científica para números muy grandes?

Sé cómo dar formato a cadenas en Python, pero estoy perdido cuando se trata de aplicarlo aquí.

df1.groupby('dept')['data1'].sum()

dept
value1       1.192433e+08
value2       1.293066e+08
value3       1.077142e+08

Esto suprime la notación científica si convierto a cadena, pero ahora me pregunto cómo formatear la cadena y agregar decimales.

sum_sales_dept.astype(str)
3
  • 2
    posible duplicado de Suprimir la notación científica en pandas? 15/01/2014 a las 13:13
  • 3
    Vi esa pregunta, pero no estoy seguro de cómo me ayuda. Solo busco preservar el dtype actual que es flotante y simplemente mostrar todos los decimales en el resultado en lugar de la notación científica. 15/01/2014 a las 13:52
  • Probablemente sea solo una cosa de exhibición. Pero si crees que hay algo en particular en tu problema que hace que el tuyo sea diferente al del enlace de Dan, entonces necesitas publicar más información sobre tu problema, preferiblemente con un pequeño conjunto de datos que reproduzca el problema. Además, ¿cuáles son dtypestus resultados? 15/01/2014 a las 14:18
298

Por supuesto, la respuesta que vinculé en los comentarios no es muy útil. Puede especificar su propio convertidor de cadenas así.

In [25]: pd.set_option('display.float_format', lambda x: '%.3f' % x)

In [28]: Series(np.random.randn(3))*1000000000
Out[28]: 
0    -757322420.605
1   -1436160588.997
2   -1235116117.064
dtype: float64

No estoy seguro de si esa es la forma preferida de hacer esto, pero funciona.

Convertir números en cadenas con fines puramente estéticos parece una mala idea, pero si tiene una buena razón, esta es una forma:

In [6]: Series(np.random.randn(3)).apply(lambda x: '%.3f' % x)
Out[6]: 
0     0.026
1    -0.482
2    -0.694
dtype: object
5
  • 1
    Gracias Dan. ¿Sabes cómo restablecer las opciones de pandas?
    Josh
    23 de enero de 2017 a las 19:04
  • 2
    @Josh Para configurar temporalmente las opciones en pandas, puede usar pandas.option_context(consulte pandas.pydata.org/pandas-docs/stable/generated/… ). 27/07/18 a las 10:41
  • 1
    A menudo, no es con fines estéticos, sino para obtener información más rápida a través de la corteza visual en grandes marcos de datos numéricos. 20/04/19 a las 18:57
  • pd.set_option ('display.float_format', lambda x: '% .3f'% x) también funcionó para mí 28 de mayo de 2019 a las 17:19
  • 9
    Esto funciona y también puede usar la notación de cadena f más nueva. Como pd.set_option('display.float_format', lambda x: f'{x:,.3f}')si también quisieras un separador de mil.
    576i
    29/10/19 a las 10:26
127

Aquí hay otra forma de hacerlo, similar a la respuesta de Dan Allan pero sin la función lambda:

>>> pd.options.display.float_format = '{:.2f}'.format
>>> Series(np.random.randn(3))
0    0.41
1    0.99
2    0.10

o

>>> pd.set_option('display.float_format', '{:.2f}'.format)
1
  • 2
    Creo que usar una cadena de formato sería más accesible para los miembros del equipo que están menos familiarizados con Python y es posible que no entiendan las funciones lambda. 12 oct 2018 a las 15:04
28

Puede usar la función de redondeo solo para suprimir la notación científica para un marco de datos específico:

df1.round(4)

o puede suprimirlo globalmente mediante:

pd.options.display.float_format = '{:.4f}'.format
17

Si desea aplicar estilo a la salida de un marco de datos en una celda de cuaderno de jupyter, puede establecer el estilo de visualización por marco de datos:

df = pd.DataFrame({'A': np.random.randn(4)*1e7})
df.style.format("{:.1f}")

ingrese la descripción de la imagen aquí

Consulte la documentación aquí .

7

Establecer un número fijo de lugares decimales a nivel mundial a menudo es una mala idea, ya que es poco probable que sea un número apropiado de lugares decimales para todos los datos que se mostrarán independientemente de la magnitud. En su lugar, intente esto que le dará notación científica solo para valores grandes y muy pequeños (y agrega un separador de miles a menos que omita el ","):

pd.set_option('display.float_format', lambda x: '%,g' % x)

O para suprimir casi por completo la notación científica sin perder precisión, intente esto:

pd.set_option('display.float_format', str)
3

Tenía varios marcos de datos con diferentes puntos flotantes, por lo que gracias a la idea de Allan se hizo una longitud dinámica.

pd.set_option('display.float_format', lambda x: f'%.{len(str(x%1))-2}f' % x)

El inconveniente de esto es que si tiene el último 0 en flotación, lo cortará. Entonces no será 0.000070, sino 0.00007.

1
  • con mucho, una de las respuestas menos votadas.
    Michael
    24 de enero a las 21:16
0

Si desea utilizar los valores, digamos que como parte de csvfile csv.writer, los números se pueden formatear antes de crear una lista:

df['label'].apply(lambda x: '%.17f' % x).values.tolist()