Frage

Das sollte einfach sein.

Hier ist meine Array (besser gesagt, ein Verfahren zum Erzeugen von repräsentativen Testarrays):

>>> 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])

Ich möchte eine Liste von Strings, wo ‚\ n'.join (list_o_strings) würde drucken:

   79.9914
   20.8
  394.0
 4661.0
    5.0
 1725.751
  391.5
19061.0
11624.7
  353.92

Ich möchte Raum-Pad auf der linken Seite und das Recht (aber nicht mehr als nötig).

Ich mag eine Null hinter dem Komma, wenn das alles ist, dass nach dem Komma ist.

Ich will nicht die wissenschaftliche Notation.

.. und ich will keine signifikanten Stellen verlieren. (In 353,98000000000002 die 2 nicht signifikant)

Ja, es ist schön .. zu wollen

Python 2.5 des %g, %fx.x usw. entweder befuddling mich, oder kann es nicht tun. Ich habe nicht import decimal noch versucht. Ich kann nicht sehen, dass NumPy tut es entweder (obwohl, sind die array.__str__ und array.__repr__ dezimal ausgerichtet ( aber manchmal wissenschaftliche zurück).

Oh, und die Geschwindigkeit zählt. Ich bin hier mit großen Arrays zu tun.

Meine aktuellen Lösungsansätze sind:

  1. auf str (a) und analysieren aus NumPy die Klammern
  2. str (e) jedes Element in dem Array und Split ( ''), dann Polster und Rekonstruieren
  3. a.astype ( 'S' + str (i)), wobei i der max (len (str (a))), dann Pad

Es scheint, wie es sollte da draußen einig off-the-shelf Lösung sein ... (aber nicht erforderlich)

Top Vorschlag nicht mit, wenn dtype ist 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
War es hilfreich?

Lösung

Es tut uns Leid, aber nach gründlicher Untersuchung ich keinen Weg finden, können die Aufgabe, die Sie ohne ein Minimum an Nachbearbeitung erfordern auszuführen (um die nachgestellten Nullen abzustreifen Sie wollen nicht sehen); so etwas wie:

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

thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]

print '\n'.join(thelist)

ist schnell und prägnant, aber bricht Ihre Einschränkung von „off-the-shelf“ zu sein - es ist vielmehr eine modulare Kombination der allgemeinen Formatierung (was fast tut, was Sie wollen, aber Blätter Hinter null Sie wollen sich verstecken) und eine RE unerwünschte nacheilenden Nullen zu entfernen. Praktisch, ich denke, es tut genau das, was Sie benötigen, aber Ihre Bedingungen wie angegeben sind, glaube ich, über eingeschränkt.

Bearbeiten : Original Frage bearbeitet wurde mehr signifikanten Stellen angeben, benötigt keinen zusätzlichen führenden Raum jenseits dem, was für die größte Zahl erforderlich ist, und bietet ein neues Beispiel (wo mein früherer Vorschlag, oben, doesn‘ t entsprechen den gewünschten Ausgang). Die Arbeit der führenden Leerzeichen entfernt werden, die zu einer Reihe von Zeichenketten üblich ist, wird am besten durchgeführt mit textwrap.dedent - aber das funktioniert auf einer einzigen Saite (mit Zeilenumbrüchen), während die erforderliche Ausgabe eine Liste von Strings ist. Kein Problem, wir werden nur die Linien zusammen, Dedent sie und verteilen sie wieder:

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)

aussendet:

      550.056103
     6773.83566
   601001.513
355425142.0
   707254.875
      883.174744
       82.232051
425076609.0
 62866263.5
      156.503068

Andere Tipps

Pythons Zeichenfolge Formatierung beide können nur die notwendigen Dezimalstellen ausdrucken (mit% g) oder einen festen Satz von Dezimalstellen verwenden (mit% f). Sie möchten jedoch nur die notwendigen Dezimalstellen auszudrucken, mit der Ausnahme, wenn die Zahl eine ganze Zahl, dann wollen Sie eine Nachkommastelle, und das macht es kompliziert.

Dies bedeutet, dass Sie am Ende mit etwas würden wie:

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)

Dies wird zunächst eine Zeichenfolge entweder mit 1 Nachkommastelle zu erstellen, wenn der Wert eine ganze Zahl ist, oder es wird mit automatischen Dezimalzahlen (aber nur bis zu 10 Nummern) drucken, wenn es nicht eine gebrochene Zahl ist. Schließlich wird es ausdrucken, so eingestellt, dass der Dezimalpunkt ausgerichtet werden.

Wahrscheinlich, aber numpy tatsächlich tut, was Sie wollen, weil Sie in der Regel es tun wollen, in der exponentiellen Modus sein, wenn es zu lang ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top