El módulo matemático de Python contiene funciones prácticas como floor
& ceil
. Estas funciones toman un número de coma flotante y devuelven el entero más cercano debajo o encima de él. Sin embargo, estas funciones devuelven la respuesta como un número de coma flotante. Por ejemplo:
import math
f=math.floor(2.3)
Ahora f
vuelve:
2.0
¿Cuál es la forma más segura de obtener un número entero de este flotante, sin correr el riesgo de errores de redondeo (por ejemplo, si el flotante es el equivalente a 1.99999) o tal vez debería usar otra función por completo?
python
math
integer
python-2.x
Booz
fuente
fuente
math.floor
devuelve un flotante en v2.6 , pero devuelve un entero en v3 . En este punto (casi seis años después del OP), este problema podría aparecer raramente.Respuestas:
Todos los enteros que se pueden representar con números de coma flotante tienen una representación exacta. Por lo tanto, puede usarlo con seguridad
int
en el resultado. Las representaciones inexactas ocurren solo si está tratando de representar un número racional con un denominador que no es una potencia de dos.¡Que esto funcione no es trivial en absoluto! Es una propiedad de la representación de coma flotante IEEE que int∘floor = ⌊⋅⌋ si la magnitud de los números en cuestión es lo suficientemente pequeña, pero son posibles diferentes representaciones donde int (floor (2.3)) podría ser 1.
Para citar de Wikipedia ,
fuente
El uso
int(your non integer number)
lo clavará.fuente
floor
redondea hacia abajo mientras queint
redondea hacia 0.int(-2.3)
en Python Distribution Canopy 2.7.6 y obtuve-2
lo esperado. Los números enteros pueden ser negativos, de la misma manera en la definición matemática formal.int(-2.3)
da-2
como dices, porque se redondea hacia0
, es decir , hacia arriba en este caso. Por el contrario, la pregunta original utilizadamath.floor
, que siempre se redondea:math.floor(-2.3)
da-3.0
.math.floor
, y esta respuesta muestra cómo convertir un flotante en un entero. Tome el flotadormath.floor
yint
int(math.floor(2.3))
Podrías usar la función redonda. Si no utiliza ningún segundo parámetro (número de dígitos significativos), creo que obtendrá el comportamiento que desea.
Salida inactiva.
fuente
round
también devuelve un número flotante, al menos en Python 2.6.round
y losfloor
enteros devueltos en Python 3.x. Así que supongo que la pregunta se refiere a Python 2.x.int(round(2.65))
?round(6.5)
da 6? Parece un pococeil()
flotante cuando hay un 5 inmediato (o mayor hasta 9) después del decimal en todos los demás casos. ¿Por qué esto no funciona en este caso? o cualquier otro caso cuando el número termina con un seis y hay un 5 justo después del decimal ...Combinando dos de los resultados anteriores, tenemos:
Esto convierte un flotador en un entero de manera bastante confiable.
fuente
float
representación de un número más grande de lo queint
puede contener un normal . En Python 2, ¿hayfloat
valores que solo puede representar usando unlong
(después del redondeo)?int()
función produce unaint
o unalong
función de lo que se necesita ...Esta publicación explica por qué funciona en ese rango .
En un doble, puede representar enteros de 32 bits sin ningún problema. No puede haber problemas de redondeo. Más precisamente, los dobles pueden representar todos los enteros entre 2 53 y -2 53 inclusive .
Breve explicación : un doble puede almacenar hasta 53 dígitos binarios. Cuando necesita más, el número se rellena con ceros a la derecha.
Se deduce que 53 unidades es el número más grande que se puede almacenar sin relleno. Naturalmente, todos los números (enteros) que requieren menos dígitos se pueden almacenar con precisión.
Agregar uno a 111 (omitido) 111 (53 unidades) produce 100 ... 000, (53 ceros). Como sabemos, podemos almacenar 53 dígitos, lo que hace que el margen cero más a la derecha.
De aquí viene el 2 53 .
Más detalles: debemos considerar cómo funciona el punto flotante IEEE-754.
El número se calcula de la siguiente manera (excluyendo casos especiales que son irrelevantes aquí):
donde sesgo = 2 exponente - 1 - 1 , es decir, 1023 y 127 para precisión doble / simple respectivamente.
Sabiendo que multiplicar por 2 X simplemente cambia todos los bits X lugares a la izquierda, es fácil ver que cualquier número entero debe tener todos los bits en la mantisa que terminan a la derecha del punto decimal a cero.
Cualquier número entero excepto cero tiene la siguiente forma en binario:
Debido a que excluimos cero, siempre habrá un MSB que sea uno, razón por la cual no se almacena. Para almacenar el entero, debemos llevarlo a la forma mencionada anteriormente: -1 signo × 1.mantissa × 2 exponente - sesgo .
Eso dice lo mismo que desplazar los bits sobre el punto decimal hasta que solo esté el MSB hacia la izquierda del MSB. Todos los bits a la derecha del punto decimal se almacenan en la mantisa.
A partir de esto, podemos ver que podemos almacenar como máximo 52 dígitos binarios aparte del MSB.
Se deduce que el número más alto donde todos los bits se almacenan explícitamente es
Para esto, necesitamos establecer el exponente, de modo que el punto decimal se desplace 52 lugares. Si tuviéramos que aumentar el exponente en uno, no podríamos conocer el dígito de derecha a izquierda después del punto decimal.
Por convención, es 0. Al establecer toda la mantisa en cero, recibimos el siguiente número:
Es un 1 seguido de 53 ceros, 52 almacenados y 1 agregado debido al exponente.
Representa 2 53 , que marca el límite (tanto negativo como positivo) entre el que podemos representar con precisión todos los enteros. Si quisiéramos agregar uno a 2 53 , tendríamos que establecer el cero implícito (indicado por el
x
) en uno, pero eso es imposible.fuente
math.floor
siempre devolverá un número entero y, porint(math.floor(some_float))
lo tanto , nunca introducirá errores de redondeo.Sin
math.floor(some_large_float)
embargo, el error de redondeo ya podría haberse introducido , o incluso cuando se almacena un gran número en un flotante en primer lugar. (Grandes números pueden perder precisión cuando se almacenan en flotadores).fuente
int
yfloor
devuelve diferentes valores para números negativos, por supuesto.Si necesita convertir una cadena flotante a un int, puede usar este método.
Ejemplo:
'38.0'
a38
Para convertir esto en un int, puedes lanzarlo como flotante y luego int. Esto también funcionará para cadenas flotantes o cadenas enteras.
Nota : Esto eliminará cualquier número después del decimal.
fuente
Otro ejemplo de código para convertir un real / flotante en un entero usando variables. "vel" es un número real / flotante y se convierte al siguiente INTEGER más alto, "newvel".
fuente
Dado que está solicitando la forma "más segura", le proporcionaré otra respuesta que no sea la respuesta principal.
Una manera fácil de asegurarse de no perder precisión es verificar si los valores serían iguales después de convertirlos.
Si el flotante es 1.0 por ejemplo, 1.0 es igual a 1. Por lo tanto, la conversión a int se ejecutará. Y si el valor flotante es 1.1, int (1.1) equivale a 1, y 1.1! = 1. Por lo tanto, el valor seguirá siendo un valor flotante y no perderá ninguna precisión.
fuente
df ['Column_Name'] = df ['Column_Name']. astype (int)
fuente