Comment supprimer la notation scientifique lors de l'impression de valeurs flottantes?

147

Voici mon code:

x = 1.0
y = 100000.0    
print x/y

Mon quotient s'affiche sous la forme 1.00000e-05.

Existe-t-il un moyen de supprimer la notation scientifique et de la faire apparaître comme 0.00001? Je vais utiliser le résultat sous forme de chaîne.

Mat
la source
1
1/10000 = 0,0001 = 1,00000e-04
Adrian Archer
@AA, en supposant que c'était une faute de frappe dans la déclaration d'affectation, je l'ai corrigé.
Dana
Il est décevant qu'aucune des réponses ici ne réponde à la question. Ce serait bien s'il y avait un moyen d'empêcher python (3) d'utiliser la notation scientifique du tout sauf lorsque spécifié explicitement. Toutes les réponses exigent que l'utilisateur supprime explicitement la notation scientifique, ce qui n'est pas la même chose que de supprimer généralement l'utilisation implicite de la notation scientifique à partir de python.
BLUC

Réponses:

64
'%f' % (x/y)

mais vous devez gérer vous-même la précision. par exemple,

'%f' % (1/10**8)

affichera uniquement les zéros.
les détails sont dans la documentation

Ou pour Python 3, l'ancien formatage équivalent ou le formatage de style plus récent

SilentGhost
la source
7
Je suggère de clarifier votre déclaration en disant: "vous gérez vous-même l' affichage de la précision". La précision réelle (interne à Python) n'est pas modifiée, comme c'est souvent le cas dans d'autres langages.
JS.
92

En utilisant la version la plus récente ''.format(n'oubliez pas de spécifier le nombre de chiffres après le que .vous souhaitez afficher, cela dépend de la taille du nombre flottant). Voir cet exemple:

>>> a = -7.1855143557448603e-17
>>> '{:f}'.format(a)
'-0.000000'

comme indiqué ci-dessus, la valeur par défaut est de 6 chiffres! Ce n'est pas utile pour notre exemple de cas, donc à la place, nous pourrions utiliser quelque chose comme ceci:

>>> '{:.20f}'.format(a)
'-0.00000000000000007186'

Mettre à jour

À partir de Python 3.6, cela peut être simplifié avec le nouveau littéral de chaîne formaté , comme suit:

>>> f'{a:.20f}'
'-0.00000000000000007186'
Aziz Alto
la source
Mais comment faire cela tout en précisant des chiffres significatifs?
Marses
Je suppose qu'en utilisant une variable, donnez-lui le nombre de chiffres souhaité et utilisez-le à la place du nombre littéral, par exemplef"{a:.{precision}f}"
Aziz Alto
49

Avec les nouvelles versions de Python (2.6 et versions ultérieures), vous pouvez utiliser ''.format()pour accomplir ce que @SilentGhost a suggéré:

'{0:f}'.format(x/y)
nmichaels
la source
1
Est-ce vraiment ce que vous voulez? Je n'ai pas: >>> print('{:f}'.format(0.000000123)) 0.000000
duality_
1
@duality, vous devrez peut-être spécifier la précision. '{0:.10f}'
nmichaels
24

Une autre option, si vous utilisez des pandas et que vous souhaitez supprimer la notation scientifique pour tous les flotteurs, consiste à ajuster les options des pandas.

import pandas as pd
pd.options.display.float_format = '{:.2f}'.format
Josh Janjua
la source
10

La plupart des réponses ci-dessus exigent que vous spécifiiez une précision. Mais que faire si vous voulez afficher des flottants comme celui-ci, sans zéros inutiles:

1
0.1
0.01
0.001
0.0001
0.00001
0.000001
0.000000000001

numpy a une réponse: np.format_float_positional

import numpy as np

def format_float(num):
    return np.format_float_positional(num, trim='-')
Dennis Golomazov
la source
5

Cela fonctionnera pour n'importe quel exposant:

def getExpandedScientificNotation(flt):
    str_vals = str(flt).split('e')
    coef = float(str_vals[0])
    exp = int(str_vals[1])
    return_val = ''
    if int(exp) > 0:
        return_val += str(coef).replace('.', '')
        return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
    elif int(exp) < 0:
        return_val += '0.'
        return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
        return_val += str(coef).replace('.', '')
    return return_val
Capitaine Concombre
la source
4

Ceci utilise la réponse du capitaine Cucumber , mais avec 2 ajouts.

1) permettant à la fonction d'obtenir des nombres de notation non scientifique et de les renvoyer tels quels (vous pouvez donc envoyer beaucoup de données indiquant que certains des nombres sont 0,00003123 contre 3,123e-05 et ont toujours des fonctions.

2) prise en charge supplémentaire des nombres négatifs. (dans la fonction d'origine, un nombre négatif finirait par 0,0000-108904 à partir de -1,08904e-05)

def getExpandedScientificNotation(flt):
    was_neg = False
    if not ("e" in flt):
        return flt
    if flt.startswith('-'):
        flt = flt[1:]
        was_neg = True 
    str_vals = str(flt).split('e')
    coef = float(str_vals[0])
    exp = int(str_vals[1])
    return_val = ''
    if int(exp) > 0:
        return_val += str(coef).replace('.', '')
        return_val += ''.join(['0' for _ in range(0, abs(exp - len(str(coef).split('.')[1])))])
    elif int(exp) < 0:
        return_val += '0.'
        return_val += ''.join(['0' for _ in range(0, abs(exp) - 1)])
        return_val += str(coef).replace('.', '')
    if was_neg:
        return_val='-'+return_val
    return return_val
Finn42
la source
3

En plus de la réponse de SG, vous pouvez également utiliser le module Decimal:

from decimal import Decimal
x = str(Decimal(1) / Decimal(10000))

# x is a string '0.0001'
Dana
la source
14
il se tourne vers la notation scientifique pour les valeurs inférieures à 1e-6
SilentGhost
2

Si c'est un stringalors utilisez le intégré floatdessus pour faire la conversion par exemple: print( "%.5f" % float("1.43572e-03")) réponse:0.00143572

U-571
la source
1

Puisqu'il s'agit du meilleur résultat sur Google, je publierai ici après avoir échoué à trouver une solution à mon problème. Si vous cherchez à mettre en forme la valeur d'affichage d'un objet flottant et à la faire rester un flottant - pas une chaîne, vous pouvez utiliser cette solution:

Créez une nouvelle classe qui modifie la façon dont les valeurs flottantes sont affichées.

from builtins import float
class FormattedFloat(float):

    def __str__(self):
        return "{:.10f}".format(self).rstrip('0')

Vous pouvez modifier vous-même la précision en modifiant les valeurs entières dans {:f}

Marques Jared
la source
-1

En utilisant 3.6.4, j'avais un problème similaire qui, de manière aléatoire, un nombre dans le fichier de sortie serait formaté avec une notation scientifique lors de l'utilisation de ceci:

fout.write('someFloats: {0:0.8},{1:0.8},{2:0.8}'.format(someFloat[0], someFloat[1], someFloat[2]))

Tout ce que j'avais à faire pour le réparer était d'ajouter 'f':

fout.write('someFloats: {0:0.8f},{1:0.8f},{2:0.8f}'.format(someFloat[0], someFloat[1], someFloat[2]))
Scott Lohr
la source
-1

À partir de la version 3.6 (fonctionne probablement également avec les versions 3.x légèrement plus anciennes), voici ma solution:

import locale
locale.setlocale(locale.LC_ALL, '')

def number_format(n, dec_precision=4):
    precision = len(str(round(n))) + dec_precision
    return format(float(n), f'.{precision}n')

Le but du precisioncalcul est de s'assurer que nous avons suffisamment de précision pour éviter la notation scientifique (la précision par défaut est toujours de 6).

L' dec_precisionargument ajoute une précision supplémentaire à utiliser pour les points décimaux. Comme cela utilise le nformat, aucun zéros insignifiant ne sera ajouté (contrairement aux fformats). nprendra également en charge le rendu des entiers déjà ronds sans décimale.

nnécessite une floatentrée, donc le casting.

Alex S
la source