Seite 1 von 2

einlesen und verarbeiten von daten

Verfasst: Freitag 29. Mai 2009, 12:19
von quant
hallo

ich hoffe das ich hier richtig bin :) und zwar versuche ich mit py folgendes zu realisieren:

ich hab datenfiles welche aus wörten und zahlen bestehen. genauer ist oben ein kopf mit worten wo dahinter zahlen sind. das ist etwa 25 zeilen groß. dann kommen etwa 100 zeilen die nur aus spalten mit zahlen bestehen. das ganze wiederholt sich so 1 mio mal... dieses nenn ich ich folgenden events.

was ich machen will ist folgendes: ich will mit py den datei einlesen und dann eventweise durchgehen. die daten nach den strings splitten, ich dachte da an sowas wie splitte bei lehrzeichen und speichere die zahl hinter dem wort in eine variable. ausserdem will ich manche variablen auch hochzählen, also zb eine events variable die jedenmal wenn ein neues event begint incrementiert wird...

wichtig ist dass ich später mit den zahlen auch arbeiten kann, also rechnen.

ich hab sowas schonmal in perl geschrieben und hänge es auch mal an damit ihr vlt besser seht was ich meine...

währe echt cool wenn ihr mir da kurz bei helfen könnt, weil ich bin py anfänger und konnte noch nicht wirklich was brauchbares zu finden

PERL CODE:

Code: Alles auswählen

#!/usr/bin/perl

while(<>) {  
 @stuff=split(' '); #hier zerlege ich alles nach lehrzeichen

 if(/NAME/){ #suche nach dem string name
 }
 elsif(/projectile:/){ #suche weiter nach projectile:
  $protar=$_           # speichere den wert nach projectile: ab in $protar
 }
 elsif(/equation_of_state:/){ 
  $ecm=$stuff[5];
  $midy=log($ecm/0.938);
  $elab=$stuff[3];
  $plab=$stuff[7];
 }
 elsif(/event#/){
  $noe++;                    # numbers of events: noe
 }
 elsif(/pott:/){
  $vspot=$stuff[1]
 }      
 else{
  if($#stuff==14){  #hier wird geprüft ob die folgende tabelle aus 14 spalten besteht

   @x=@stuff[0..3];   
   @p=@stuff[4..7];
   @id=@stuff[8..11];

   $mass=$id[0];
   $ityp=$id[1];
   $iz2=$id[2];
   $charge=$id[3];

# ab hier steht folgende info zur verfuegung:

# stuff[0] = r_0    = $x[0]
# stuff[1] = r_x    = $x[1]
# stuff[2] = r_y    .
# stuff[3] = r_z    .
# stuff[4] = p_0    = $p[0]
# stuff[5] = p_x    = $p[1]
# stuff[6] = p_y    .
# stuff[7] = p_z    .
# stuff[8] = mass   = $id[0]
# stuff[9] = ityp   = $id[1]
# stuff[10]= iz2    = $id[2]
# stuff[11]= charge = $id[3]

hoffe ihr versteht was ich meine, ich kann auch wenns hilft ein event aus der datenbank file anhängen

Verfasst: Freitag 29. Mai 2009, 12:24
von Hyperion
Also erst einmal wäre es wichtig, noch mehr Infos über das "wieso" sowie das Datenformat zu wissen.

Was hast Du denn später damit vor? Welche Infos benötigst Du im Speicher? Alles? Nur einen Teil der Datei?

Dann muss man mehr über das Format wissen. Wie sieht die Grammatik der Datei aus?

Dann kann man überlegen, ob man sich einen "echten" Parser schreiben sollte, oder das ganze per simpler Bordmittel realisiert. (Ggf. gibt es dann auch für die ein oder andere Passage der Datei schon Bordmittel, denke da grad ans CSV-Modul).

Außerdem schadet es nicht zu wissen, welche Infos in Python-Variablen übernommen werden sollen. Da das ganze recht groß zu sein scheint, könnte das relevant für die Einelese-Strategie sein.

Verfasst: Freitag 29. Mai 2009, 12:29
von BlackJack
@quant: Das Tutorial aus der Python-Dokumentation sollte man auf jeden Fall mal durchgearbeitet haben.

Verfasst: Freitag 29. Mai 2009, 12:33
von quant
huhu

also ich will damit werte aus meinen simulationen auswerten... diese werden in eine datei geschrieben, ich nenn sie mal datei.dat
ich brauch im prinzip die gleichen wie ich mit dem perlscript abgespeichert hab. ich hänge hier im anhang mal ein event als beispiel an... dieses wiederholt sich ja im prinzip die ganze zeit nur mit neuen daten.

was ich mache ist im prinzip ein event einlesen dann die daten aus dem event verarbeiten, wie zb 2 werte multiplizieren und die ergebnisse wieder in einem neuen array speichern dann das nächste etc. und am ende zb. dann das neu produzierte array ausgeben

hier mal das beispielt des event files in abgespreckter version, in der regel sind die spalten mit dn zahlen im unteren 2/3 größer


ok hab sausgelagert wie mir empfolen wurde :) vielen dank

http://paste.pocoo.org/show/119733/

Verfasst: Freitag 29. Mai 2009, 12:58
von BlackJack
Ein grösseres Beispiel findet man hier: urqmd.ftn14.

Und in diesem PDF, scheinbar die Anleitung für das Programm mit dem die Daten erzeugt werden können, findet sich ab Seite 20 eine Beschreibung des Formats: urqmd-user.pdf.

Ist ein "fixed" Format, das heisst man kann mittels "slicing" die Daten extrahieren und eigentlich recht einfach einen ordentlichen Parser schreiben.

Verfasst: Freitag 29. Mai 2009, 13:01
von Hyperion
Puh ... wer denkt sich solche Formate aus? Sieht echt grausam aus ...

Es hakt bei mir aber immer noch an der Grammatik. Woran erkennt man denn, dass ab Zeile 17 diese Zahlenkolonnen losgehen? Ist das immer die 17. Zeile nach dem "NAME: ..."? Sind zwischen diesen Blöcken immer Leerzeichen? (also quasi im Anschluss an Deinen Paste vor dem nächsten großen Block?)

Ich habe das Gefühl, da braucht es wirkliche eine präzise Grammatik! Das anders lösen zu wollen führt imho zu nichts wirklich zuverlässigem!

Wieso eigentlich brauchst Du das jetzt in Python, wo Du doch das Perl-Script schon hast?

Verfasst: Freitag 29. Mai 2009, 13:03
von Hyperion
BlackJack hat geschrieben:Ist ein "fixed" Format, das heisst man kann mittels "slicing" die Daten extrahieren und eigentlich recht einfach einen ordentlichen Parser schreiben.
Ah, ok. Dann hab ich das falsch eingeschätzt.

Verfasst: Freitag 29. Mai 2009, 13:04
von quant
joa also ich will später mit den extrahierten zahlen kompliziertere rechnungen machen und naja ich will bischen in python reinschnuppern :)

also beim perlscript erkenn ich es daran dass 14 lehrzeichen aufeinander folgen aber im prinzip sieht der kopf oben immer gleich aus und die menge der 15 spalten mit zahlen darunter kann variieren

Verfasst: Freitag 29. Mai 2009, 13:11
von Hyperion
Naja, BlackJack hat Dir ja schon ne gute Hilfe gepostet. ALso erst einmal solltest Du Dir das Python-Tutorial angucken. Dort werden Dir die wichtigsten Sprachelemente vermittelt.

Das "Slicing" wurde ja auch von BlackJack erwähnt. Daher sollte das dann wirklich halbwegs einfach gehen. Da werden dann wohl Sachen wie "".split() o.ä. auf Dich zu kommen. Imho aber alles Dinge, die im Tutorial angesprochen werden.

Verfasst: Freitag 29. Mai 2009, 13:13
von quant
jo danke schonma... ich guck mir das gleich mal an und wenn ich bissi code hab und irgendwo hänge paste ichs hier

lg

Verfasst: Freitag 29. Mai 2009, 14:01
von quant
so also ich hab ma bissi probiert ich kann auf alle fälle jetzt zeilen nach lehrzeichen trennen und diese in ein array schreiben, ich kann dann auch wenn ich weiss wo also an welcher stelle die sachen stehen sie aufrufen und verwenden. das problem was ich hab, diese werte sind strings und keine zahlen mehr, kann ich die irgendwie convertieren ?

ich hab erst mal angefangen eine zeile der data zu verwenden, aber wie könnte ich jetzt zb. eine datei öffnen und diese einlesen ? am besten eventweise also so wie ich das im perlscript mache, wo ich es in eine while schleife packe und immer eventweise durch gehe ?

Code: Alles auswählen



import string

#f = open("apal26-qmda-4gev.f14","r");
data = "projectile:  (ityp, char)   -1  -1   target:  (mass, char)   26  13"

gesplit = string.split(data)

#if gesplit[] == projectile:
#  print "gespliteetere"


pro = gesplit[3], gesplit[4]
print pro

#f.close()



Verfasst: Freitag 29. Mai 2009, 14:15
von Hyperion
Du solltest dringend einen Blick ins Tutorial werfen! Da wird das alles erklärt.

Des weiteren hilft hier auch die Forensuche weiter. Dort findet man allerhand zu vielen Basis-Themen.

Verfasst: Freitag 29. Mai 2009, 14:30
von BlackJack
@quant: Das was Du Array nennst sind Listen. Da musst Du ein wenig mit der Terminologie aufpassen, denn es gibt in der Standardbibliothek auch das `array`-Modul und mit `numpy` ein verbreitetes Paket, das auch einen `array`-Typ hat, die beide spezieller sind, als der Grunddatentyp `list`.

Verfasst: Freitag 29. Mai 2009, 14:47
von quant
hmmm danke :)

ich bin glaub ich auch schon ein bischen weiter, bekomm aber jetzt einen fehler den ich nicht verstehe

Code: Alles auswählen


import string

fdata = open("apal26-qmda-4gev.f14","r")
for line in fdata:
	splittn = line.split(" ")
	while True:
#		uqmd = UQMD
		if UQMD in splittn:
			print "drinne"
		else:
			print "nicht drinne"		
fdata.close()

$ python new.py
Traceback (most recent call last):
File "new.py", line 25, in <module>
if UQMD in splittn:
NameError: name 'UQMD' is not defined

Verfasst: Freitag 29. Mai 2009, 14:50
von BlackJack
@quant: Naja wo definierst Du denn den Namen? Nirgends. Namen sind keine Zeichenketten. In Perl übrigens auch nicht.

Verfasst: Freitag 29. Mai 2009, 16:03
von quant
hmmm vlt hat grad wer zeit mir dabei zu helfen, ich bin soweit dass ich die data einlesen und in tupel zerlegen kann, nur wenn ich nach projectile suche und dort den 4. und 5. eintrag haben will und diesen dann z.b. in einem anderne tupel zu speichern bekomm ich die meldung

:~/Desktop/kaons$ python new.py
UQMD
Traceback (most recent call last):
File "new.py", line 31, in <module>
print splittn[3]
IndexError: tuple index out of range

Code: Alles auswählen

import string


	
fdata = open("apal26-qmda-4gev.f14","r")
while True:
	for line in fdata:
#	splittn = line.split()
		splittn = line.partition(" ")
	
		if ("UQMD") in splittn:
			print splittn[0]
		if ("projectile:") in splittn:
			print splittn[3]
#		else:
#			print "nicht drin"

#		pro = splittn.index("projectile:")+3
#		print pro
		
fdata.close()

Verfasst: Freitag 29. Mai 2009, 16:10
von Hyperion
Gib Dir doch mal "splittn" aus ... dann wirst Du sehen, dass es kein 4. Feld gibt!

btw: bei if's kann (sollte) man die Klammern weglassen!

Code: Alles auswählen

# unschön
if ("UQMD") in splittn:
    pass
# besser
if "UQMD" in splittn:
    pass

Verfasst: Freitag 29. Mai 2009, 16:12
von derdon
str.partition gibt ein tupel der Länge 3 zurück, d.h. das letzte Element hat den Index 2:

Code: Alles auswählen

In [35]: foo = "a string containing the letters UQMD and some more words at the end"

In [36]: foo.partition("UQMD")
Out[36]: ('a string containing the letters ', 'UQMD', ' and some more words at the end')

In [37]: foo.partition("UQMD")[0]
Out[37]: 'a string containing the letters '

In [38]: foo.partition("UQMD")[2]
Out[38]: ' and some more words at the end'

Verfasst: Freitag 29. Mai 2009, 16:14
von quant
jo alles klar hab ma die klammern weg

und ja es gibt keinen [3], aber die frage ist warum, weil die line doch viel größer ist und viel mehr inhalte hat, ich verweise nochma auf die gepaste datei im anhang weiter oben

Verfasst: Freitag 29. Mai 2009, 16:16
von Hyperion
quant hat geschrieben: und ja es gibt keinen [3], aber die frage ist warum, weil die line doch viel größer ist und viel mehr inhalte hat, ich verweise nochma auf die gepaste datei im anhang weiter oben
Und ich verweise mal auf die Doku zu str.partition()! ;-) Da steht es doch genau erklärt ... Du suchst wohl eher str.split()!