Dateien mit Schleife erstellen

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
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Hallo,

ich soll eine riesen Datei (data) auswerten, die ich mit csv2rec eingelesen habe. In dieser Datei sind Zeiten und Messergebnisse. Es gibt eine 2. Datei (time) in der die Zeiten stehen zu denen ich die Messwerte haben möchte. Also muss ich filtern. Dazu wollte ich diese Loop benutzen. (Sie funktioniert auch so wie sie soll ;-) )

Code: Alles auswählen

for t in time:
	ID , start , end = t[0] , t[1] , t[2]
	mid = np.where(data['id']==ID)
	subset1 = data[:][mid[0]]
	for i, t in enumerate(time):
		start , end = t[1] , t[2]
		uts = np.where(logical_and(subset1['utseconds'] >= start , subset1['utseconds'] <= end))
		subset2 = subset1[:][uts[0]]

So nun habe ich das Problem, dass er mir ja subset2 immer wieder überschreibt und ich so nur die letzten Werte habe.
Ich möchte aber, dass er mir so gesehen jedes subset2 speichert. Ich muss aber noch darauf zu greifen können, also nicht gleich in eine Textdatei.
Am besten wäre noch er würde mir das Subset2 gleich nach der ID benennen.

Aber leider scheitere ich daran.

Könnt ihr mir helfen?

Danke
Zuletzt geändert von max2331 am Freitag 15. April 2011, 08:40, insgesamt 1-mal geändert.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

max2331 hat geschrieben:So nun habe ich das Problem, dass er mir ja subset2 immer wieder überschreibt und ich so nur die letzten Werte habe.
Ich möchte aber, dass er mir so gesehen jedes subset2 speichert. Ich muss aber noch darauf zu greifen können, also nicht gleich in eine Textdatei.
Am besten wäre noch er würde mir das Subset2 gleich nach der ID benennen.
Das schreit doch nach einem Dictionary.

Code: Alles auswählen

data = {}
id = 5
data[id] = [23, 42]
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Hi

hmm mit Dictionaries hatte ich bis jetzt noch gar nichts am Hut. Ich hatte gehofft ich müsste mich nicht in noch mehr einlesen.

Gibt es nicht eine Möglichkeit das er mir Arrays ausgibt, wie z.B subset21, subset22, subset23, etc?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dictionaries sind einer der grundlegensten Datentypen, welche du früher oder später so oder so verstehen musst. Außerdem ist das Konzept nicht sonderlich schwer und in allen Tutorials erläutert.
Das Leben ist wie ein Tennisball.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

max2331 hat geschrieben:hmm mit Dictionaries hatte ich bis jetzt noch gar nichts am Hut. Ich hatte gehofft ich müsste mich nicht in noch mehr einlesen.
Dictionaries sollte man kennen da sie eine der Basis-Datenstrukturen von Python darstellen und wirklich schwierig sind sie nun wirklich nicht.
max2331 hat geschrieben:Gibt es nicht eine Möglichkeit das er mir Arrays ausgibt, wie z.B subset21, subset22, subset23, etc?
Das ist kein Array. Das sind unterschiedlich lautende Bezeichner. Da der Code nicht selbstmodifizierend ist kannst du so etwas nicht verwenden. Man möchte so etwas auch nicht verwenden. Variablendurchnummerierer gehören geteert und gefedert. Solche Daten gehören in ein Dictionary oder in eine Liste.

Ein Dictionaryzugriff ist wirklich einfach. Wenn deine ID, wie oben angedeutet, eine Zahl wie z.B. 23 ist, dann kannst du in einem Dictionary namens subset wie folgt auf den Inhalt zugreifen.

Code: Alles auswählen

subset[23]
Du kannst dir auch alle Keys (IDs) eines Dictionaries holen:

Code: Alles auswählen

for key in subset.iterkeys():
    print key
Schau dir einfach mal die Dokumentation dazu an.
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Na gut ihr habt mich überzeugt :-)

Könntet ihr mir vll einen Tipp geben wie ich nun meine subsets ind das Dictionary befördern kann.
Wie es prinzipiel geht weis ich jetzt, aber wie mache ich das in meiner Schleife?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Da gibt es keinen Unterschied zum "prinzipiellen" Einsatz.
Du kannst dir sogar deinen Bezeichner wie in deinem ersten Post beschrieben ueber Formatstrings zusammensetzen: `"subset%d" % i` und den dann im Dictionary verwenden. Allerdings ist das nicht unbedingt die beste Variante, aber dazu fehlt hier Kontext.
BlackJack

@max2331: Ich verstehe die innere Schleife nicht so ganz. Dir ist klar, dass Du da aus `subset1`, was ja auf Werte für eine bestimmte ID begrenzt ist, auch Werte anhand von Zeiten bekommst, die zu anderen IDs gehören!? Ist das so gewollt?
BlackJack

@max2331: Was noch auffällt: Warum benutzt Du `np.where()` wenn Du davon sowieso nur den ersten Teil des Ergebnistupels brauchst? Ebenso ist das ``[:]`` bei `data` und `subset1` sinnfrei.

`recarray`\s haben den Vorzug, dass man per ``.``-Operator auf die Spalten zugreifen kann -- man kann sich also ein paar Zeichen für den Zugriff über den Index-Operator sparen.

Ausserdem könntest Du etwas grosszügiger mit Leerzeichen sein, damit das alles nicht so aneinander klebt und leichter lesbar wird.

Letztendlich sollte das hier äquivalent zu Deinem Quelltextabschnitt sein:

Code: Alles auswählen

for id, _start, _end in time:
    subset1 = data[data.id == id]
    for i, (_id, start, end) in enumerate(time):
        subset2 = subset1[subset1.utseconds >= start & subset1.utseconds <= end]
(Das "&" ist ein einzelnes "&" -- doofe Forensoftware…)
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Also nochmal kurz zur Erklärung.
Ich suche mir in der großen Datei erst alle IDs die ich haben möchte, und dann zu den jeweiligen IDs noch Zeitintervalle und möchte dann für diese Zeitintervalle meine Messergebnisse. Dann will ich später aus 2 Werten noch was berechnen und nun alle gefilterten Daten in einer Datei speichern.

Wie kann ich es machen, dass er mir alle subset2 untereinander zusammensetzt?
BlackJack

@max2331: Erstelle eine Liste mit den Subsets und füge die dann nach der Schleife mit `numpy.concatenate()` zusammen.

Hast Du über meine Frage über die innere Schleife nachgedacht, dass Du da die Zeitintervalle für *alle* IDs aus den Daten für jede *einzelne* ID ermittelst?
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

BlackJack hat geschrieben:Hast Du über meine Frage über die innere Schleife nachgedacht, dass Du da die Zeitintervalle für *alle* IDs aus den Daten für jede *einzelne* ID ermittelst?
Irgendwie versteh ich leider nicht genau auf was du hinaus willst. Ich möchte erst alles nach ID filtern, und dann das gefilterte nochmal nach Zeiten filtern.
BlackJack

@max2331: Du filterst die Daten erst nach einer bestimmten ID, sagen wir mal 1. Und dann holst Du Dir aus den Daten alle Datensätze zu den Zeiten von *allen* IDs -- nicht nur zur ID 1. Minimalbeispiel:

Daten:
id;utseconds;...
1;15;...
1;35;...

ID/Zeiten:
id;start;end
1;10;20
2;30;40

Soll da jetzt für ID 1 nur der erste Datensatz im Ergebnis sein oder beide? Im Moment sind es beide, weil bei den Zeiten auch '2;30;40' berücksichtigt wird.
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

BlackJack hat geschrieben:
Letztendlich sollte das hier äquivalent zu Deinem Quelltextabschnitt sein:

Code: Alles auswählen

for id, _start, _end in time:
    subset1 = data[data.id == id]
    for i, (_id, start, end) in enumerate(time):
        subset2 = subset1[(subset1.utseconds >= start) & (subset1.utseconds <= end)]
Wenn ich diesen Code ausführe bekommen ich in Pylab:

"The truth value of an array with more than one element is ambigous.
Use a.any() or a.all()."

Um es einfacher zu halten soll er mir nun einfach alles Subsets untereinander anhängen. Das wollte ich mit vstack machen.

Code: Alles auswählen

for t in time:
	mission , start , end = t[0],t[1],t[2]
	mid = np.where(data['missionid'] == mission)
	subset1 = data[:][mid[0]]
	for i, t in enumerate(time):
		start , end = t[1] , t[2]
		uts = np.where(logical_and(subset1['utseconds'] >= start, subset1['utseconds'] <= end))
		subset2 = subset1[:][uts[0]]
		if new_data == None:
			new_data = subset2
		else:
			new_data = np.vstack((new_data,subset2))
Die kleine if-Schleife kommt da her das bei vstack die Arrays gleich Größe haben müssen und ich das so lösen wollte.

Also wie bekomme ich es hin das er mir jedes Subset unter das Vorhergehende anhängt?
Zuletzt geändert von max2331 am Freitag 15. April 2011, 19:32, insgesamt 1-mal geändert.
BlackJack

@max2331: Ah Mist, Operatorvorrang -- man muss Klammern um die beiden Vergleichsausdrücke machen, die mit `&` verknüpft werden. Dann sollte es gehen.

Zur ``if``-Shleife: http://if-schleife.de/

Theoretisch sollte das so mit `numpy.vstack()` funktionieren, ist aber unschön weil bei jedem Schleifendurchlauf dann ein neues Array angelegt wird und die alten Inhalte dahin umkopiert werden. Wenn Du die Subsets erst in einer Liste sammelst und nach der Schleife mit `numpy.concatenate()` zusammensetzt, dann muss nur einmal ein neues grosses Array erstellt werden, in das die alten hinein kopiert werden.

Die Frage mit den IDs/Zeiten hast Du jetzt immer noch nicht beantwortet. Das sieht IMHO komisch aus.
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Betreffs den IDs:
Wenn ich mir das Subset ausgeben lassen (im Moment ja nur das Letzte da es ja die Anderen überschreibt) dann sieht es so aus wie ich es haben möchte. Ich habe nur die Werte zu den IDs und Zeiten die ich "time" angegeben habe.
Leider komme ich jetzt demnächst nicht mehr dazu es weiter auszuprobieren (Klausur nächste Woche).
Werde aber am Ball bleiben und geg. nochmal berichten.

Danke bis dahin
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

@ BlackJack:
Also dein Code macht genau das Selbe wie meiner.

Könntest du mir bitte kurz schreiben wie der Code aussehen müsste, das ich das mit Listen und concatenate machen kann, mein Ansatz mit vstack funktioniert leider nicht.

Ich habe jetzt noch das Ausprobiert:

Code: Alles auswählen

for mission, start, end in time:
    subset1 = data[data.missionid == mission]
    for i, (mission, start, end) in enumerate(time):
        subset2 = subset1[(subset1.utseconds >= start) & (subset1.utseconds <= end)]
	new_data=numpy.concatenate((new_data,subset2),axis=0)
Eigentlich scheint es das zu machen was es soll, aber ich kann z.B nicht mehr mit

Code: Alles auswählen

print new_data['missionid']
mir die ganze Spalte anzeigen lassen.

Wäre super wenn ihr mir helfen könntet!!
Danke
BlackJack

@max2331: Es kann doch nicht so schwer sein eine Liste mit den Teilergebnissen zu erstellen. :roll: Man erstellt am Anfang eine leere Liste, hängt da die Zwischenergebnisse an, und fügt die dann am Ende mit `numpy.concatenate()` zusammen.
max2331
User
Beiträge: 13
Registriert: Montag 11. April 2011, 09:53

Ja leider habe ich gerade ein Haufen um die Ohren und keine Zeit mich im Moment weiter in Python einzulesen, deshalb auch meine Bitte m Hilfe
Antworten