¿Cómo obtener números después del punto decimal?


Respuestas:


28

Un enfoque fácil para ti:

number_dec = str(number-int(number))[1:]

30
Ejercicio para el lector: haz que funcione para números mayores o iguales a 10
intuido el

11
number_dec = str(number-int(number)).split('.')[1]
Ryan Allen

28
Votar en contra porque este es un enfoque innecesariamente complicado. La respuesta que busqué fue la siguiente 5.55 % 1, que también es una respuesta más generalmente útil: se puede usar el enfoque de división de módulo en varios idiomas, mientras que la respuesta anterior es específica de Python.
Guiso

3
NOTA: ¡ Esta solución devuelve una cadena que incluye el punto ( .55), que puede que no espere debido al título de la pregunta!
T. Christiansen

8
str(5.55 - int(5.55))[1:]devuelve en .5499999999999998lugar de lo .55mencionado en la pregunta.
Cristian Ciupitu

199
5.55 % 1

Tenga en cuenta que esto no le ayudará con los problemas de redondeo de coma flotante. Es decir, puede obtener:

0.550000000001

O de lo contrario, un poco por debajo del 0,55 que espera.


7
En cuanto a modf, también puede atornillar la precisión: math.modf(5.55)volverá (0.5499999999999998, 5.0).
bereal

1
¿Alguien sabe cuál sería la operación más rápida, este método descrito anteriormente, o: float b = a - int (a)? Sospecho que es más tarde, pero quería ver si había confirmación
hokkuk

4
En una Raspberry Pi, este método x%1fue casi dos veces más rápido que los métodos x-int(x)y modf(x)[0](los tiempos fueron 980ns, 1.39us y 1.47us promediaron más de 1000000 ejecuciones). Mi valor para xsiempre fue positivo, así que no tuve que preocuparme por eso.
coderforlife

Definitivamente el funcionamiento del módulo es más rápido. No tiene que hacer ninguna búsqueda de nombres. Mientras que llamar a la función int busca las variables globales.
Enrico Borba

no me apetece tener un frac ()
mckenzm

155

Utilice modf :

>>> import math
>>> frac, whole = math.modf(2.5)
>>> frac
0.5
>>> whole
2.0

2
Buena solución, pero la math.modf(2.53) = (0.5299999999999998, 2.0)respuesta esperada es 0.53
Lord Loh.

4
@LordLoh. eso se debe al redondeo de punto flotante y sucederá con cualquier método.
Rena

@LordLoh. Intente usar round (0.5299999999999998, 2) para obtener 0.53. Otra forma es usar Decimal del paquete decimal. docs.python.org/2/library/decimal.html
SirJ

57

Qué pasa:

a = 1.3927278749291
b = a - int(a)

b
>> 0.39272787492910011

O, usando numpy:

import numpy
a = 1.3927278749291
b = a - numpy.fix(a)

33

Con el decimalmódulo de la biblioteca estándar, puede conservar la precisión original y evitar problemas de redondeo de punto flotante:

>>> from decimal import Decimal
>>> Decimal('4.20') % 1
Decimal('0.20')

Como algunas notas en los comentarios, floatprimero tendrá que convertir los mensajes nativos en cadenas.


Para el beneficio del autor de la pregunta original: los flotantes deben convertirse en cadenas antes de que puedan convertirse en decimales. Entonces, si tiene n = 5.55, n es un flotante, y debería hacerlo Decimal(str(n)) % 1para obtener la parte fraccionaria. (Esto no es necesario si tiene un número entero, pero no hace daño.)
poco todo el

2
@intuited: no necesita ser decimal, también funciona para float: 10.0/3 % 1al menos en mi sistema
aherok

2
Puede usar from_float en lugar de usar una cadena. d = Decimal.from_float (1.2)
Matthew Purdon

@intuited ¿Cómo se obtiene la parte decimal como un número entero? He intentado los métodos to_integer () pero el tipo sigue siendo Decimal.
D1X

1
@MatthewPurdon: si usa Decimal.from_float(1.2)(que ahora se puede escribir como Decimal(1.2)) tendrá problemas de redondeo, que esta respuesta estaba tratando de evitar.
John Y


5

similar a la respuesta aceptada, un enfoque aún más fácil usando cadenas sería

def number_after_decimal(number1):
    number = str(number1)
    if 'e-' in number: # scientific notation
        number_dec = format(float(number), '.%df'%(len(number.split(".")[1].split("e-")[0])+int(number.split('e-')[1])))
    elif "." in number: # quick check if it is decimal
        number_dec = number.split(".")[1]
    return number_dec

number = 5.55; "." in numberda TypeError: argument of type 'float' is not iterable. ¿Y qué harías tú si number = 1e-5?
Mark Dickinson

@marcar la pregunta es ¿Cómo obtengo los números después de un punto decimal? por lo que el usuario espera flotar en notación decimal (no notación científica), también agregué un bloque para notación científica
yosemite_k

Un número es un número; son solo representaciones de un número que pueden estar en notación científica. Así que "flotar en notación decimal" no tiene mucho sentido aquí; cuando Python lo ve, es solo un float; Python no tiene ningún conocimiento de en qué formato se expresó originalmente. Mi number = 1e-5ejemplo se aplica igualmente bien a number = 0.00001: la strrepresentación del número está en notación científica. Por cierto , querrás lidiar con él e+también e-.
Mark Dickinson

4
import math
orig = 5.55
whole = math.floor(orig)    # whole = 5.0
frac = orig - whole         # frac = 0.55

>>> frac 0.5499999999999998
macm

4
>>> n=5.55
>>> if "." in str(n):
...     print "."+str(n).split(".")[-1]
...
.55

2
Esto está bien para números de variedades de jardín, pero no funciona tan bien para números lo suficientemente grandes (o pequeños) como para requerir notación científica.
poco todo el

2

Esta es una solución que probé:

num = 45.7234
(whole, frac) = (int(num), int(str(num)[(len(str(int(num)))+1):]))

2

A veces, los ceros finales son importantes

In [4]: def split_float(x):
   ...:     '''split float into parts before and after the decimal'''
   ...:     before, after = str(x).split('.')
   ...:     return int(before), (int(after)*10 if len(after)==1 else int(after))
   ...: 
   ...: 

In [5]: split_float(105.10)
Out[5]: (105, 10)

In [6]: split_float(105.01)
Out[6]: (105, 1)

In [7]: split_float(105.12)
Out[7]: (105, 12)

¿Qué hace esto por 0.000005?
Aditya Patnaik

2

Con solo usar la división de operador simple '/' y la división de piso '//' , puede obtener fácilmente la parte fraccionaria de cualquier flotante dado.

number = 5.55

result = (number/1) - (number//1)

print(result)

1

Utilice floor y reste el resultado del número original:

>> import math #gives you floor.
>> t = 5.55 #Give a variable 5.55
>> x = math.floor(t) #floor returns t rounded down to 5..
>> z = t - x #z = 5.55 - 5 = 0.55

5
Si va a hacerlo import math, ¿por qué no usarlo math.modf()?
ire_and_curses

@ire_and_curses: estoy proporcionando una solución alternativa al problema.

1
floor hace lo mismo que lanzar a un int, por lo que podría reemplazar math.floor (t) con int (t)
QuantumKarl

@QuantumKarl No, son diferentes. math.floor(-1.1) == -2pero int(-1.1) == -1. Aunque para esta pregunta usar intes más correcto.
Lambda Fairy

1

Los números flotantes no se almacenan en formato decimal (base10). Lea la documentación de Python sobre esto para saber por qué. Por lo tanto, no es aconsejable obtener una representación en base 10 de un flotante.

Ahora existen herramientas que permiten el almacenamiento de datos numéricos en formato decimal. A continuación se muestra un ejemplo con la Decimalbiblioteca.

from decimal import *

x = Decimal('0.341343214124443151466')
str(x)[-2:] == '66'  # True

y = 0.341343214124443151466
str(y)[-2:] == '66'  # False

1

Ejemplo:

import math
x = 5.55
print((math.floor(x*100)%100))

Esto le dará dos números después del punto decimal, 55 de ese ejemplo. Si necesita un número, reduce en 10 los cálculos anteriores o aumenta dependiendo de cuántos números desee después del decimal.


Esto es bueno porque devuelve un valor no fraccionario, pero se romperá en números negativos
Miau

Desafortunadamente, no funciona la mayor parte del tiempo. @Meow
Marqués de Lorne


0

Qué pasa:

a = 1.234
b = a - int(a)
length = len(str(a))

round(b, length-2)

Salida:
print(b)
0.23399999999999999
round(b, length-2)
0.234

Dado que la ronda se envía a la longitud de la cadena de decimales ('0.234'), podemos simplemente menos 2 para no contar el '0.' y calcular el número deseado de puntos decimales. Esto debería funcionar la mayoría de las veces, a menos que tenga muchos lugares decimales y el error de redondeo al calcular b interfiera con el segundo parámetro de round.


¿Alguna explicación?

0

Es posible que desee probar esto:

your_num = 5.55
n = len(str(int(your_num)))
float('0' + str(your_num)[n:])

Regresará 0.55.


0
number=5.55
decimal=(number-int(number))
decimal_1=round(decimal,2)
print(decimal)
print(decimal_1)

salida: 0.55


0

Vea lo que hago a menudo para obtener números después del punto decimal en Python 3:

a=1.22
dec=str(a).split('.')
dec= int(dec[1])

0

Si está usando pandas:

df['decimals'] = df['original_number'].mod(1)

0

Otra opción sería usar el remódulo con re.findallo re.search:

import re


def get_decimcal(n: float) -> float:
    return float(re.search(r'\.\d+', str(n)).group(0))


def get_decimcal_2(n: float) -> float:
    return float(re.findall(r'\.\d+', str(n))[0])


def get_int(n: float) -> int:
    return int(n)


print(get_decimcal(5.55))
print(get_decimcal_2(5.55))
print(get_int(5.55))

Salida

0.55
0.55
5

Si desea simplificar / modificar / explorar la expresión, se explica en el panel superior derecho de regex101.com . Si lo desea, también puede ver en este enlace cómo coincidiría con algunas entradas de muestra.


Fuente

¿Cómo deshacerse de números flotantes adicionales en la resta de Python?


0

Descubrí que números realmente grandes con partes fraccionarias realmente grandes pueden causar problemas al usar el módulo 1 para obtener la fracción.

import decimal

>>> d = decimal.Context(decimal.MAX_PREC).create_decimal(
... '143000000000000000000000000000000000000000000000000000000000000000000000000000.1231200000000000000002013210000000'
... )
...
>>> d % 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
decimal.InvalidOperation: [<class 'decimal.DivisionImpossible'>]

En lugar de eso, tomé la parte integral y la resté primero para ayudar a simplificar el resto.

>>> d - d.to_integral()
Decimal('0.1231200000000000000002013210')

0

Otro ejemplo usando modf

from math import modf
number = 1.0124584

# [0] decimal, [1] integer
result = modf(number)
print(result[0])
# output = 0124584
print(result[1])
# output = 1

0

Una solución es usar módulo y redondeo.

import math

num = math.fabs(float(5.55))
rem = num % 1

rnd_by =   len(str(num)) - len(str(int(num))) - 1

print(str(round(rem,rnd_by)))

Tu salida será 0.55



-2

Otra solución loca es (sin convertir en una cadena):

number = 123.456
temp = 1

while (number*temp)%10 != 0:
    temp = temp *10
    print temp
    print number

temp = temp /10
number = number*temp
number_final = number%temp
print number_final
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.