einlesen und verarbeiten von daten

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.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
BlackJack

@quant: Das Tutorial aus der Python-Dokumentation sollte man auf jeden Fall mal durchgearbeitet haben.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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/
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.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

jo danke schonma... ich guck mir das gleich mal an und wenn ich bissi code hab und irgendwo hänge paste ichs hier

lg
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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


Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
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`.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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
BlackJack

@quant: Naja wo definierst Du denn den Namen? Nirgends. Namen sind keine Zeichenketten. In Perl übrigens auch nicht.
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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()
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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'
quant
User
Beiträge: 34
Registriert: Freitag 29. Mai 2009, 12:06

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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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()!
Antworten