*.csv Parser

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
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Hallo Leute!

Ich habe eine Frage die im Prinzip einfach ist. Ich weiß aber nicht wie, und ob man sie so einfach Lösen kann.

Ich lese eine Datei (*.csv) ein. Diese enthält unter anderem in gewisser Weise eine Laufende Nummer. Das file wird geparst und verschiedene Informationen extrahiert. Mein Problem nun: Ich möchte beim erreichene eines bestimmten Inhalts einer Zelle, das das Parsen wieder von vorne startet.

Ich benutzte das "for" Konstrukt.

Code: Alles auswählen

with open(file,"rb") as measureobjectdata:
                data = csv.reader(measureobjectdata, delimiter=';', quotechar='|')
                for row in data:
                         if row(0) == "xy":
                                     #Starte von vorne
                                     pass
Hier sollte dann quasi row wieder auf 0 zurückgesetzt werden. Gibt es die Möglichkeit bzw. ist es möglich in eine bestimmte Zeile der Datei zu "springen"?

Grüße Killigen
Zuletzt geändert von Anonymous am Mittwoch 20. April 2016, 08:52, insgesamt 1-mal geändert.
Grund: Quelltext in Code-Tags gesetzt.
BlackJack

@Killigen: Das geht so nicht, Du müsstest an der Stelle einfach abbrechen und alles noch mal machen. Wobei die Frage ist ob man tatsächlich das Parsen noch mal machen möchte, und nicht vielleicht lieber im ersten Schritt alles parst bis zu der Stelle und dann danach immer wieder über die bereits geparsten Daten iteriert.
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@BlackJack:
Doch es geht. Habe es mittlerweile gelöst:

Code: Alles auswählen

with open(file,"rb") as measureobjectdata:
	data = csv.reader(measureobjectdata, delimiter=';', quotechar='|')
	for row in data:
		if "data" in row[0]:
			measureobjectdata.seek(0)
So springt er wieder zum Anfang zurück und parst alles erneut. Mit dem anderen was du gesagt hast, hast du im Prinzip vollkommen recht. Einmal alles einlesen und dann über die gelesenen Daten iterieren. Die Größer dieser Daten kann dabei aber immens groß werden. Darum kann ich nicht alles im RAM behalten und muss deshalb immer wieder erneut iterieren.

Gruß
Killigen
BlackJack

@Killigen: Das ist keine Lösung weil das nur zufällig funktioniert. Falls es das überhaupt tut und Du den Fehler einfach nur noch nicht bemerkt hast. Sobald die CSV-Implementierung nämlich einen Puffer verwendet, und davon würde ich ausgehen, wirkt sich das `seek()` erst beim nächsten Lesezugriff auf die Datei aus und man hat davor noch ”Datenmüll” aus dem Puffer als Datensatz oder gar Daten*sätze*, bevor dann tatsächlich wieder der erste Datensatz kommt.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Killigen: Dein Problem hört sich für mich so an, als ob Du eigentlich etwas ganz anderes willst. Hilfreich wäre zu wissen, warum Du wieder von vorne anfangen willst?
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@Sirius: Naja ich habe eine Datei mit 2 Spalten in der einen stehen Zeitdauern in der anderen eine 1 oder eine 0. Ich möchte berechnen wie lange die 1 in der Gesamtzeit aktiv war. Dazu werden zwei Intervalle und ein Intervallschritt vom Nutzer definiert. Das Eine Intervall gibt an für welchen Gesamtzeitraum die Berechnungen stattfinden sollen. Das andere gibt genau das Intervall an für das berechnet werden soll wie lange die 1 aktiv war. Der Intervallschritt gibt in Prozent an um wie viel Prozent des kleinen Intervalls (in Zeiteinheiten) das Intervall weitergeschoben werden muss. Daher muss ich von 0-x die Aktivphase (1) berechnen und bei Verschiebung um 50% (also Intervallschritt=50) von x/2 bis x+x/2. Daher muss ich immer weider von vorne starten... Und zwischenspeichern ist aufgrund der Menge der Daten nicht möglich.

Und noch eine weitere Frage:
Ich verwende eine *.ini Datei. Diese wurde über den RawConfigParser ausgelesen. So viel als Kurzinformation, ist aber im Prinzip irrelevant. Worum es mir geht ist folgendes. Ich habe eine Option in dieser Datei in welche vom Nutzer mit Komma getrennt Parameter eingegeben werden können. Dem Nutzer steht es dabei frei wie viele er eingeben will. Ich möchte diese durch Komma getrennten Werte nun in meinem Programm in einer Liste abspeichern... Gibt es hier irgendeine Funktion oder kann man das sinnvoll mit regex o.ä. lösen?

Beispiel:
Eingabe:
option=a,b,c,d,e,f
Ausgabe
print list
["a","b","c","d","e","f"]
Benutzeravatar
miracle173
User
Beiträge: 127
Registriert: Samstag 6. Februar 2016, 00:28

Killigen hat geschrieben: (...)
Und noch eine weitere Frage:
(...)
Für eine weitere Frage wäre ein neuer Thread sinnvoll
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Alles klar hab einen Neuen eröffnet... Bitte da dann antworten! Danke :)
Name: Stringmanipulation/ Regex/ RawConfigParser
BlackJack

@Killigen: Nicht das ich die Beschreibung jetzt verstanden hätte, aber ich sehe da noch keinen Grund warum man die Datei immer wieder erneut von vorne verarbeiten muss.
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

@Blackjack: Es werden eben immer die relativen Aktivphasen berechnet und bei einer Verschiebung um 50% muss ich zuerst die Phase von Anfang bis zum Ende des Intervalls rechnen und dann wird das Intervall um 50% des Intervalls weitergeschoben das heißt der Anfang des Intervalls ist jetzt 0+50%des Intervalls und das Ende ist das vorherige Ende + 50%des Intervalls... Und dadurch muss ich eben immer wieder von vorne bzw. vom Anfang des Intervalls anfangen... Verständlich?
BlackJack

@Killigen: Und dafür kann man nicht einfach die Daten für ein Intervall im Speicher behalten? Und eventuell auch komprimieren? Also aufeinanderfolgende 0en und 1en zu einem Datensatz zusammenfassen‽

Edit: Was auch einen Vorteil bringen könnte wenn man wahlfreien Zugriff auf die Daten braucht, wäre die CSV-Datei in eine Binärdatei umwandeln mit festen Datensatzgrössen. Das dann vielleicht in Verbindung mit dem `mmap`-Modul, damit sich das Betriebssystem um eine effiziente Speicherverwaltung kümmern kann. Oder dann vielleicht auch mit Numpy das Array in den Speicher einblenden und dessen Operationen verwenden.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Killigen: wenn Du immer Blöcke von x/2-Zeilen anschaust, ladt die Datei einfach in diesen Blöcken und verarbeite immer den aktuellen mit dem Vorgängerblock. Allgemein, man nimmt eine collections.deque mit einer festen Fenstergröße, und macht seine Berechnungen auf dieser Menge alle n Zeilen.
Killigen
User
Beiträge: 48
Registriert: Freitag 6. März 2015, 10:46

Naja die Größe eines Intervalls im Speicher zu behalten sollte vermutlich kein Problem sein, aber das Intervall ändert sich ja ständig... Dadruch wird es wohl schwierig...
Die beschriebene Methode wäre vielleicht eine Möglichkeit... Aber ich persönlich finde es unzureichend für einen Parser (in dem Fall csv ) dass es nicht die Möglichkeit gibt eine bestimmte Zeile anzusprechen...!?
BlackJack

@Killigen: Verrate mal wie das gehen soll in einer Textdatei, in der man allgemein nicht von einer festen Länge der Zeilen ausgehen kann, eine bestimmte Zeile anzusprechen‽ Also ohne das man alle vorhergehenden Zeilen einliest.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Killigen: natürlich kannst Du an eine bestimmte Zeile in einer Text-Datei springen - Du musst dafür nur wissen an welcher Position innerhalb der Datei diese Zeile beginnt. Dafür aber musst Du die Datei zuvor einlesen (solange die Zeilen nicht alle die gleiche Länge aufweisen). Wenn Du sie aber einmal eingelesen hast, kannst Du auch direkt auf diese Daten im RAM zugreifen (solange das RAM reicht).

Auch verstehe ich Dein Problem nicht. Nach Deiner Beschreibung hast Du eine csv-Datei mit zwei Spalten:

Spalte 1: Zeitraum (start, stopp, bzw. range)
Spalte 2: 0 | 1

Mit dieser Information kannst Du für ein bekanntes Zeitintervall den Anteil an 1-Zuständen ermitteln.
Wofür Du ein variables weiteres "inneres Intervall" benötigst, ist mir unklar.
Antworten