leerzeichengetrennte Matrix auslesen

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
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

Hallo zusammen,

seit 4 Wochen beschäftige ich mich intensiv mit Python. Bei meinem Projekt bin ich nun aber auf ein Problem gestoßen, wo ich in diesem Forum keine Lösung finden konnte. Daher die Frage an euch: Hat jemand eine Idee für folgendes Problem:

Ich habe von einem Statistikprogramm (C5/See5) folgende Ausgabe:
http://paste.pocoo.org/show/218469/

Ich möchte diese Matrix in ein zwei-dimensionales Array auslesen. Allerdings müssen hierbei die leeren Felder durch
eine 0 ersetzt werden. Ich bin soweit, dass ich die Sache in ein zwei-dimensionales Array auslesen kann, allerdings mit der Funktion "split" werden alle Leerstellen ignoriert. Ich brauche also etwas, was z.B. alle 6 Zeichen entweder den gefundenen Wert ausgibt oder bei 6 Leerzeichen eine 0. Auch kann sich die größe der Matrix ändern, wenn neue "class" hinzukommen. Bisher sieht mein (gekürzter) Code:

Code: Alles auswählen

matrix = []					       # Array für Matrix erstellen
        for count in range(0,int(a_ct)):
        count = count + 1
	nl = f.next()
        s_nl = nl.split()				# Hier brauche ich eure Hilfe
        matrix.append(s_nl)			# Zweidimensionales Array entsteht 
Aber das nützt mir nicht viel, da ich so nicht weiter rechnen kann :(
Schon mal vielen Dank für eure Ideen!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Code: Alles auswählen

s = """C5.0 [Release 2.06]  	Wed May 26 07:50:10 2010
-------------------




	   (a)   (b)   (c)   (d)   (e)   (f)   (g)   (h)   (i)   (j)   (k)    <-classified as
	  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----  ----
	   189          11           1                 2                      (a): class 2
	           1     1           1           1                            (b): class 12
	     9          30     3     2     2                                  (c): class 3
	     4                22     1     4                                  (d): class 5
	     8           4     4    23     1                                  (e): class 9
	     2     1     4     2          13     1                            (f): class 7
	     1           1                       3                            (g): class 10
	     5           8     2     1     1          11                      (h): class 14
	     2     1           1     2                 1                      (i): class 6
	     8           5                             2           2          (j): class 13
	     2                 1                                              (k): class 4"""

from pprint import pprint

matrix = [[int(t) if t else 0 for t in (line.strip("\t")[i*6:i*6+6].strip() for i in xrange(11))] 
          for line in s.splitlines()[8:]]
pprint(matrix)
Output:

Code: Alles auswählen

[[189, 0, 11, 0, 1, 0, 0, 2, 0, 0, 0],
 [0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0],
 [9, 0, 30, 3, 2, 2, 0, 0, 0, 0, 0],
 [4, 0, 0, 22, 1, 4, 0, 0, 0, 0, 0],
 [8, 0, 4, 4, 23, 1, 0, 0, 0, 0, 0],
 [2, 1, 4, 2, 0, 13, 1, 0, 0, 0, 0],
 [1, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0],
 [5, 0, 8, 2, 1, 1, 0, 11, 0, 0, 0],
 [2, 1, 0, 1, 2, 0, 0, 1, 0, 0, 0],
 [8, 0, 5, 0, 0, 0, 0, 2, 0, 2, 0],
 [2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
BlackJack

@Windsurfer: Das wird mit `str.split()` nicht gehen. Es sind ja feste Abstände, also kannst Du die Positionen der Felder innerhalb einer Zeile ausrechnen und sie mit "slicing" ausschneiden. Dann entweder in eine Zahl umwandeln oder wenn das Feld leer ist eine 0 annehmen.
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

Genial :) Und ich habe mir den ganzen Tag den Kopf drüber zerbrochen und bin gerade frustriert nach Hause gefahren.. Dann kann es ja morgen früh weiter gehen! Ich versuche dann mal deinen Code zu verstehen.
Vielen Dank! :)
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn man nicht alles auf Teufel komm raus in LCs packen würde (jetzt besonders was die Tiefe angeht), dann würde man das bestimmt noch etwas schneller verstehen. :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Windsurfer hat geschrieben: Ich habe von einem Statistikprogramm (C5/See5) folgende Ausgabe:
http://paste.pocoo.org/show/218469/
Ich kenne das Programm leider nicht, aber mal ganz naiv gefragt: Bist Du Dir wirklich sicher, dass man sich die "0" nicht doch ausgeben lassen kann? Oftmals wird das ja eher wegen der besseren Übersicht für das menschliche Auge weggelassen. Aber evtl. hat das Programm ja einen speziellen Output für spätere technische Weiterverarbeitung...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

snafu hat geschrieben: Ich kenne das Programm leider nicht, aber mal ganz naiv gefragt: Bist Du Dir wirklich sicher, dass man sich die "0" nicht doch ausgeben lassen kann?
Hier ist die Anleitung zu diesem Tool:
http://www.rulequest.com/see5-unix.html
Ganz unten stehen zusammengefasst die möglichen Optionen. Ich habe leider kenie Möglichkeit gefunden, die Matrix zu verändern. Bei über 20 "classes" sieht die Matrix anders aus - dafür habe ich auch schon zum auslesen eine Lösung gefunden.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Bißchen off-topic: Ein seltsames Programm, daß csv-Input fordert, aber nicht schreiben kann. (Jedenfalls habe ich auf der Seite nicht derartiges gesehen.) Es gibt gute, freie, sauber dokumentierte Alternativen, die sogar gut mit Python interagieren. Da wäre R (mit RPy) oder gar scipy.stats. Sorry, wenn das mit der ursprünglichen Frage nichts zu tun hat, aber vielleicht war das Kommentar doch was wert ...
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

@numerix
Ich versuche gerade die Lösung von numerix in mein Projekt zu integrieren. Bisher habe ich den Anfang der Matrix mit einer markanten Stelle im Output ermittelt und bin dann die Anzahl der Croptypes (="class") mit einer Schleife heruntergegangen. Das System bekomme ich aber nicht mit dem Code von numerix vereint :( Ich habs zwar geschafft, eine Zeile richtig auszulesen, aber durch die Schleife wird diese dann wieder überschrieben.

Daher hier die ungekürzte Ausgabe von meinem Code:
http://paste.pocoo.org/show/218776/
--> der ausgelesene Wert "a_ct" beträgt in meinem Versuch 11

So sieht das ungekürzte Outputfile aus:
http://paste.pocoo.org/show/218778/

Sorry, dass jetzt erst die ungekürzte Fassung kommt, aber ich habe gedacht, dass ich die Lösung selbst implementiert bekomme :K
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Windsurfer hat geschrieben:Sorry, dass jetzt erst die ungekürzte Fassung kommt, aber ich habe gedacht, dass ich die Lösung selbst implementiert bekomme :K
Das schaffst du auch noch ...

Code: Alles auswählen

matrix = []
for line in lines:
    matrix.append([int(t) if t else 0 for t in (line.strip("\t")[i*6:i*6+6].strip() for i in xrange(11))])
Dabei entspricht "lines" denjenigen Zeilen, die auch tatsächlich ausgewertet werden.
Jeder Schleifendurchlauf ergänzt die Matrix um 1 Zeile.
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

numerix hat geschrieben: Das schaffst du auch noch ...
Genau das habe ich gerade :D :D :D
Dafür hat es sich gelohnt, den Feierabend zu überziehen:
http://paste.pocoo.org/show/218893/

Vielen Dank!!
Benutzeravatar
Windsurfer
User
Beiträge: 11
Registriert: Mittwoch 26. Mai 2010, 11:47

Mir ist gerade aufgefallen, dass ich ja auch noch die "class" auslesen muss. Also "(a): class 2" --> davon brauche ich die 2. Das macht ja Sinn, gleich bei jedem Schleifendurchlauf mit in eine extra Matrix zu schreiben. Allerdings funktioniert meine bisherige Idee noch nicht:

Code: Alles auswählen

matrix_ct.append([int(u) if u else "class " for u in (nl.strip("class ").strip() for i in xrange(int(a_ct)))])
Edit: Ich habe es so gelöst:

Code: Alles auswählen

s_nl = nl.split()
matrix_ct.append(s_nl[len(s_nl)-1])
Antworten