Format - reguläre Ausdrücke

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kleiner.epsilon
User
Beiträge: 25
Registriert: Sonntag 31. Oktober 2010, 14:31

Hallo,
ich habe eine Datendatei, die wie folgt aussieht. Es gibt 5 Parameter, die jeweils mehrere Iterationen haben (zwischen 1 und 14).
Parameter:
1: -0.1136526E+00
2: 0.1967943E-01
3: 0.1016349E+01
4: 0.1473191E+01
5: 0.1121686E+01
*******************************************************************************
Parameter:
1: -0.1036413E+00
2: 0.1968289E-01
3: 0.1015857E+01
4: 0.1469624E+01
5: 0.1119795E+01
*******************************************************************************
Parameter:
1: 0.8895733E+00
2: 0.1999193E-01
3: 0.9663719E+00
4: 0.1117563E+01
5: 0.9311053E+00
*******************************************************************************
Da ich z.B. Parameter1 gegen Parameter2 (eigentlich jeden gegen jeden) in allen Iterationen plotten will,
sollen die schön untereinander in eine Datei geschrieben werden, am besten durch Leerzeichen getrennt.
Also schön wäre so ein Format (Kopfzeile und 1.Spalte dienen nur zur Veranschaulichung):
p1 p2 p2 p4 p5
i1 -0.1136526E+00 0.1967943E-01 ...
i2 -0.1036413E+00 0.1968289E-01
i3 0.8895733E+00 0.1999193E-01
i4 ... ...
i5
...

Mein Ansatz war folgender:

Code: Alles auswählen

par = (r'Parameter:\s*1:\s*(-?\d*\.?\d*[E]?[+-]?\d*)\s*2:\s*(-?\d*\.?\d*[E]?[+-]?\d*)\s*3:\s*(-?\d*\.?\d*[E]?[+-]?\d*)\s*4:\s*(-?\d*\.?\d*[E]?[+-]?\d*)\s*5:\s*(-?\d*\.?\d*[E]?[+-]?\d*)')

parameter_iteration = re.findall(par, text)

with open ( wegdatei , 'a') as datei:
	datei.write("%s  "%(parameter_iteration))
	datei.write("\n")
Als Ergebnis erhalte ich folgendes Format (Tupel in Liste), was mir aber nicht weiterhilft.

[('-0.1136526E+00', '0.1967943E-01', '0.1016349E+01', '0.1473191E+01', '0.1121686E+01'), ('-0.1036413E+00', '0.1968289E-01', ... ')]

Wie kann ich denn anders an die Sache rangehen, bzw. was kann ich da noch anders machen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

kleiner.epsilon hat geschrieben:Wie kann ich denn anders an die Sache rangehen, bzw. was kann ich da noch anders machen?
Reguläre Ausdrücke halte ich hier ja für übertrieben. Ein split() am Doppelpunkt müsste doch reichen.

Zum Schreiben mal folgender Ansatz:

Code: Alles auswählen

daten = (1.23, -2.34, 3.45, -4.56, 5.67)
str = '{d[0]} {d[1]} {d[2]} {d[3]} {d[4]}\n'.format(d=daten)
print str
BlackJack

@/me: Das ist nicht das gewünschte Format. Die Werte eines Blockes sollen nicht nebeneinander ausgegeben werden werden, sondern in der ersten Zeile der erste Wert von jedem Block, in der zweiten Zeile der zweite Wert von jedem Block und so weiter.
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

BlackJack hat geschrieben:@/me: Das ist nicht das gewünschte Format. Die Werte eines Blockes sollen nicht nebeneinander ausgegeben werden werden, sondern in der ersten Zeile der erste Wert von jedem Block, in der zweiten Zeile der zweite Wert von jedem Block und so weiter.
Zwischen die geschweiften Klammern ein \n setzen dürfte das Problem erledigen.

CU Uwe
---------------------------------
have a lot of fun!
BlackJack

@Käptn Haddock: Nein das tut es nicht. Dann werden zwar die Werte aus dem ersten Parameterblock zwar untereinander geschrieben, aber neben diese Werte sollen ja noch die aus den anderen Paramaterblöcken.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Den Text einfach hier einfüttern:

Code: Alles auswählen

def parse(s):
    values = []
    for m in re.finditer(r"(?m)^(Parameter:)$|^([1-5]):\s(.*)$", s):
        a, b, c = m.groups()
        if a:
            values.append([0] * 5)
        else:
            values[-1][int(b) - 1] = float(c)
    return values
Das gibt ein Array mit Arrays mit jeweils 5 Elementen. Ich gehe davon aus, dass jeder neue Datenblock mit "Parameter:" beginnt. Die Trennlinie mit den Sternchen ignoriere ich einfach. Das Ergebnis kann jetzt beliebig formatiert und ausgegeben werden.

Stefan
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@/me: Das ist nicht das gewünschte Format. Die Werte eines Blockes sollen nicht nebeneinander ausgegeben werden werden, sondern in der ersten Zeile der erste Wert von jedem Block, in der zweiten Zeile der zweite Wert von jedem Block und so weiter.
Im angegebenen Beispiel für das Wunschergebnis sieht das aber einfach transponiert aus.

Code: Alles auswählen

Eingabe:
1: -0.1136526E+00
2: 0.1967943E-01
3: 0.1016349E+01
4: 0.1473191E+01
5: 0.1121686E+01

Ausgabe:
-0.1136526E+00 0.1967943E-01 ...
Aus der Beschreibung bin ich nicht ganz schlau geworden, aber die angegebene Ausgabe favorisiert doch eher meine Interpretation.
kleiner.epsilon
User
Beiträge: 25
Registriert: Sonntag 31. Oktober 2010, 14:31

Hallo,
danke für die Tipps. Ich brauch noch eine Weile, um sie zu verstehen und auszuprobieren und hier meine Lösung/Ergebnis posten zu können.
Währendessen habe ich noch eine Frage, denn ich verstehe nicht ganz die Syntax von

Code: Alles auswählen

(r"(?m)^(Parameter:)$|^([1-5]):\s(.*)$", s)
r
(roher String, okay)
"(?m)
(was bedeutet das?)
^(Parameter:)$
(^Start, $Ende des Strings, okay)
|
(was bedeutet das? ich dachte, das heißt 'oder')
^([1-5]):
(okay)
\s(.*)$",
(bin überrascht, dass das ausreichen soll)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das Leben ist wie ein Tennisball.
Antworten