Redondeo de entradas en un Pandas DafaFrame

Utilizando :

newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean) 

cuyos rendimientos:

  Alabama_exp Credit_exp Inventory_exp National_exp Price_exp Sales_exp Quradate 2010-01-15 0.568003 0.404481 0.488601 0.483097 0.431211 0.570755 2010-04-15 0.543620 0.385417 0.455078 0.468750 0.408203 0.564453 

Me gustaría obtener los números decimales redondeados a dos dígitos y multiplicados por 100; por ejemplo, .568003 debería estar 57 jugando con él durante un tiempo sin éxito; intentado esto

 newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean).apply(round(2)) #and got: TypeError: ("'float' object is not callable", u'occurred at index Alabama_exp') 

Intenté una serie de otros enfoques en vano, pero la mayoría se quejan de que el elemento no es un objeto flotante … Veo que el objeto de la serie Pandas tiene un método redondo, pero el DF no probé el uso de df.apply, pero se quejó del problema del objeto flotante.

Solo usa numpy.round , por ejemplo:

 100 * np.round(newdf3.pivot_table(rows=['Quradate'], aggfunc=np.mean), 2) 

Siempre que la ronda sea apropiada para todos los tipos de columna, esto funciona en un DataFrame .

Con algunos datos:

 In [9]: dfrm Out[9]: ABC 0 -1.312700 0.760710 1.044006 1 -0.792521 -0.076913 0.087334 2 -0.557738 0.982031 1.365357 3 1.013947 0.345896 -0.356652 4 1.278278 -0.195477 0.550492 5 0.116599 -0.670163 -1.290245 6 -1.808143 -0.818014 0.713614 7 0.233726 0.634349 0.561103 8 2.344671 -2.331232 -0.759296 9 -1.658047 1.756503 -0.996620 In [10]: 100*np.round(dfrm, 2) Out[10]: ABC 0 -131 76 104 1 -79 -8 9 2 -56 98 137 3 101 35 -36 4 128 -20 55 5 12 -67 -129 6 -181 -82 71 7 23 63 56 8 234 -233 -76 9 -166 176 -100 

Desde Pandas 0.17, los DataFrames tienen un método ‘redondo’ :

 df =newdf3.pivot_table(rows=['Quradate'],aggfunc=np.mean) df.round() 

Lo que incluso te permite tener diferente precisión para cada columna.

 df.round({'Alabama_exp':2, 'Credit_exp':3}) 

Para un DataFrame tamaño DataFrame , applymap será applymap lento, ya que está aplicando una función de Python elemento por elemento en Python (es decir, no hay ninguna aceleración de Cython). Es más rápido de usar apply con functools.partial :

 In [22]: from functools import partial In [23]: df = DataFrame(randn(100000, 20)) In [24]: f = partial(Series.round, decimals=2) In [25]: timeit df.applymap(lambda x: round(x, 2)) 1 loops, best of 3: 2.52 s per loop In [26]: timeit df.apply(f) 10 loops, best of 3: 33.4 ms per loop 

Incluso podría crear una función que devuelva una función parcial que pueda aplicar:

 In [27]: def column_round(decimals): ....: return partial(Series.round, decimals=decimals) ....: In [28]: df.apply(column_round(2)) 

Como sugiere @EMS, también puede usar np.round , ya que DataFrame implementa el atributo __array__ y envuelve automáticamente muchos de los numpy de numpy. También es aproximadamente el doble de rápido con el marco que se muestra arriba:

 In [47]: timeit np.round(df, 2) 100 loops, best of 3: 17.4 ms per loop 

Si tienes columnas no numéricas puedes hacer esto:

 In [12]: df = DataFrame(randn(100000, 20)) In [13]: df['a'] = tm.choice(['a', 'b'], size=len(df)) In [14]: dfnum = df._get_numeric_data() In [15]: np.round(dfnum) 

para evitar el error críptico arrojado por numpy cuando intenta redondear una columna de cadenas.

Lo dejo aquí para explicar por qué el enfoque del OP arrojó un error, pero las soluciones posteriores son mejores.

La mejor solución es simplemente usar el método round serie:

 In [11]: s Out[11]: 0 0.026574 1 0.304801 2 0.057819 dtype: float64 In [12]: 100*s.round(2) Out[12]: 0 3 1 30 2 6 dtype: float64 

También puede .astype('int') allí, dependiendo de lo que quiera hacer a continuación.

Para comprender por qué su enfoque no funcionó, recuerde que la round funciones necesita dos argumentos, el número de decimales y los datos que se redondearán . En general, para aplicar funciones que toman dos argumentos, puede “curry” la función así:

 In [13]: s.apply(lambda x: round(x, 2)) Out[13]: 0 1.03 1 1.30 2 -1.06 dtype: float64 

Como DSM señala en los comentarios, para este caso uno realmente necesita el enfoque de curry, porque no hay un método de redondeo para DataFrames. df.applymap(...) es el camino a seguir.