Question

Cela devrait être facile.

Voici mon tableau (plutôt une méthode de génération de tableaux de tests représentatifs):

>>> ri = numpy.random.randint
>>> ri2 = lambda x: ''.join(ri(0,9,x).astype('S'))
>>> a = array([float(ri2(x)+ '.' + ri2(y)) for x,y in ri(1,10,(10,2))])
>>> a
array([  7.99914000e+01,   2.08000000e+01,   3.94000000e+02,
         4.66100000e+03,   5.00000000e+00,   1.72575100e+03,
         3.91500000e+02,   1.90610000e+04,   1.16247000e+04,
         3.53920000e+02])

Je veux une liste de chaînes où '\ n'.join (list_o_strings) serait imprimé:

   79.9914
   20.8
  394.0
 4661.0
    5.0
 1725.751
  391.5
19061.0
11624.7
  353.92

Je souhaite placer le pad à gauche et à droite (mais pas plus que nécessaire).

Je veux un zéro après la décimale, si c'est tout ce qui se trouve après la décimale.

Je ne veux pas de notation scientifique.

.. et je ne veux pas perdre de chiffres significatifs. (dans 353.98000000000002 le 2 n'est pas significatif)

Oui, c'est bien de vouloir ..

Les % g,% fx.x , etc. de Python 2.5, me pardonnent ou ne le peuvent pas. Je n'ai pas encore essayé importer un nombre décimal . Je ne vois pas que NumPy le fasse aussi (bien que le tableau .__ str __ et array .__ repr __ sont alignés sur les décimales (mais renvoient parfois des valeurs scientifiques).

Oh, et la vitesse compte. Je traite de grands tableaux ici.

Mes solutions actuelles sont les suivantes:

  1. pour str (a) et analyser les crochets de NumPy
  2. str (e) chaque élément du tableau et scission ('.') puis pad et reconstruction
  3. à a.astype ('S' + str (i)) où i est le max (len (str (a))), puis pad

Il semble qu'il devrait exister une solution prête à l'emploi ... (mais pas obligatoire)

La suggestion du haut échoue lorsque dtype est float64:

>>> a
array([  5.50056103e+02,   6.77383566e+03,   6.01001513e+05,
         3.55425142e+08,   7.07254875e+05,   8.83174744e+02,
         8.22320510e+01,   4.25076609e+08,   6.28662635e+07,
         1.56503068e+02])
>>> ut0 = re.compile(r'(\d)0+)
>>> thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
>>> print '\n'.join(thelist)
  550.056103
 6773.835663
601001.513
355425141.8471
707254.875038
  883.174744
   82.232051
425076608.7676
62866263.55
  156.503068
Était-ce utile?

La solution

Désolé, mais après une enquête approfondie, je ne trouve aucun moyen d’effectuer la tâche dont vous avez besoin sans un minimum de post-traitement (pour supprimer les zéros que vous ne voulez pas voir en fin de liste); quelque chose comme:

import re
ut0 = re.compile(r'(\d)0+

est rapide et concis, mais vous permet de ne plus être "disponible", - Il s'agit plutôt d'une combinaison modulaire de formatage général (qui fait presque tout ce que vous voulez, mais que vous voulez masquer après le zéro) et d'un RE pour supprimer les zéros de fin non désirés. En pratique, je pense que cela répond exactement à vos besoins, mais les conditions énoncées sont, je crois, excessives.

Modifier : la question d'origine a été modifiée pour spécifier des chiffres plus significatifs, ne pas exiger d'espace supplémentaire au-delà de celle requise pour le plus grand nombre, et fournir un nouvel exemple (où ma suggestion précédente, ci-dessus, ne ne correspond pas à la sortie souhaitée). La meilleure solution consiste à textwrap.dedent - mais cela fonctionne sur une seule chaîne (avec des nouvelles lignes) alors que la sortie requise est une liste de chaînes. Pas de problème, nous allons simplement rassembler les lignes, les dédentir et les scinder à nouveau:

import re
import textwrap

a = [  5.50056103e+02,   6.77383566e+03,   6.01001513e+05,
         3.55425142e+08,   7.07254875e+05,   8.83174744e+02,
         8.22320510e+01,   4.25076609e+08,   6.28662635e+07,
         1.56503068e+02]

thelist = textwrap.dedent(
        '\n'.join(ut0.sub(r'\1', "%20f" % x) for x in a)).splitlines()

print '\n'.join(thelist)

émet:

      550.056103
     6773.83566
   601001.513
355425142.0
   707254.875
      883.174744
       82.232051
425076609.0
 62866263.5
      156.503068
) thelist = [ut0.sub(r'\1', "%12f" % x) for x in a] print '\n'.join(thelist)

est rapide et concis, mais vous permet de ne plus être "disponible", - Il s'agit plutôt d'une combinaison modulaire de formatage général (qui fait presque tout ce que vous voulez, mais que vous voulez masquer après le zéro) et d'un RE pour supprimer les zéros de fin non désirés. En pratique, je pense que cela répond exactement à vos besoins, mais les conditions énoncées sont, je crois, excessives.

Modifier : la question d'origine a été modifiée pour spécifier des chiffres plus significatifs, ne pas exiger d'espace supplémentaire au-delà de celle requise pour le plus grand nombre, et fournir un nouvel exemple (où ma suggestion précédente, ci-dessus, ne ne correspond pas à la sortie souhaitée). La meilleure solution consiste à textwrap.dedent - mais cela fonctionne sur une seule chaîne (avec des nouvelles lignes) alors que la sortie requise est une liste de chaînes. Pas de problème, nous allons simplement rassembler les lignes, les dédentir et les scinder à nouveau:

<*>

émet:

<*>

Autres conseils

Le formatage de chaîne Pythons peut à la fois n’imprimer que les décimales nécessaires (avec% g) ou utiliser un ensemble fixe de décimales (avec% f). Toutefois, vous souhaitez imprimer uniquement les décimales nécessaires, sauf si le nombre est un nombre entier, vous souhaitez une décimale, ce qui complique les choses.

Cela signifie que vous obtiendrez quelque chose comme:

def printarr(arr):
    for x in array:
        if math.floor(x) == x:
            res = '%.1f' % x
        else:
            res = '%.10g' % x
        print "%*s" % (15-res.find('.')+len(res), res)

Ceci créera d’abord une chaîne avec soit une décimale, si la valeur est un nombre entier, soit une impression avec des décimales automatiques (mais uniquement jusqu’à 10 nombres) s’il ne s’agit pas d’un nombre fractionnaire. Enfin, il l’imprimera, ajusté afin que le point décimal soit aligné.

Probablement, cependant, numpy fait ce que vous voulez, car vous voulez généralement qu'il soit en mode exponentiel s'il est trop long.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top