Tabellen zeilenabhängig zerlegen

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
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Hallo zusammen,

ich habe eine csv-Datei, die ungefähr auf diese Art aufgebaut ist:

1;valxn;xcoord;ycoord;valym
1;valxn;xcoord;ycoord;valym
1;valxn;xcoord;ycoord;valym
.
.
.
;;;;
2;valxn;xcoord;ycoord;valym
2;valxn;xcoord;ycoord;valym
2;valxn;xcoord;ycoord;valym
.
.
usw. bis
.
13;valxn;xcoord;ycoord;valym

mit sehr vielen Werten.
Nun würde ich gerne für 1, 2, 3 ..., 13 der ersten Spalte jeweils eine neue csv erstellen. Da ich noch recht frisch im Umgang mit Python bin, wäre es super, wenn ihr mir dabei helfen könntet.

Danke schonmal

yourself
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo soll man da ansetzen? "recht frisch" kann ja so ziemlich alles bedeuten. Wo konkret hast Du Probleme bei der Aufgabe?

Da es sich um eine csv-Datei handelt, ist der erste Ansatzpunkt das csv-Modul.
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Ok um genau zu sein, bin ich blutiger Anfänger.
Folgendes habe ich mir bisher zusammenreimen können. Dabei wird die Tabelle schon soweit definiert, wie ich sie haben möchte.

Code: Alles auswählen

import csv
with open("20201001.csv") as csvdat:
	csv_obj = csv.reader(csvdat, delimiter=';')
	print(csv_obj)
	for hrz in csv_obj:

   	if hrz[0] == '1':
      	print(hrz)
Diese print(hrz) möchte ich nun als neues csv-file ausgeben. Diesen Schritt werde ich dann händisch von 1-13 durchführen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@yourself: keine Tabs und Leerzeichen mischen, denn dann kommt sowas unverständliches raus, wie Du hier gepostet hast. Benutze immer vier Leerzeichen pro Ebene.
Alles in Python ist ein Objekt, das Anhängsel bei csv_obj ist also ziemlich nichtssagend.
Beim Öffnen von Text-Dateien muß immer das richtige Encoding angegeben werden und bei CSV-Datein zusätzlich newline=""
Was soll die Abkürzunge `hrz` bedeuten? Benutze niemals Abkürzugen, die machen nur Dir und anderen das Lesen schwer.

Code: Alles auswählen

import csv

with open("20201001.csv", encoding="ASCII", newline="") as file:
    rows = csv.reader(file, delimiter=';')
    for row in rows:
        if row[0] == '1':
            print(row)
Jetzt willst Du nach dem ersten Element groupieren, dafür gibt es groupby.

Code: Alles auswählen

import csv
from itertools import groupby
from operator import itemgetter

with open("20201001.csv", encoding="ASCII", newline="") as file:
    all_rows = csv.reader(file, delimiter=';')
    for file_index, rows in groupby(all_rows, itemgetter(0)):
        if file_index:
            print(file_index, list(rows))
Und jetzt mußt Du nur noch die Zeilen wieder mit dem csv-Modul in einzelne Dateien speichern. Der letzte Schritt sei Dir zur Übung überlassen.
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Vielen Dank @sirius3!!
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Ich schaffe es nicht. :?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Was schaffst Du nicht? An welcher Stelle kommst Du nicht weiter? Was hast Du versucht? Was ist das Resultat und wie weicht es von dem, was Du willst/erwartest ab?
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Also nach Anwendung deines Codes erhalte ich 13 Gruppen, die nach der ersten Spalte benannt sind, oder? In diesen Gruppen sind x Listen, die ich gerne separiert voneinander in eine neue csv-Datei schreiben würde.

Daher muss ich, um die gewünschte Gruppe auszuwählen den index_file definieren:

Code: Alles auswählen

if file_index == '1':
Dadurch bekomme ich Gruppe 1 mit x Listen:

1 [[ ][ ][ ]...[ ]]

Wie kann ich nun diese Listen aus der Gruppe in deine Datei schreiben? Dafür habe ich csv.writer probiert, verstehe aber nicht welche variablen ich wo platzieren muss um das File zu schreiben. Wenigstens wird es schon erzeugt ...

Code: Alles auswählen

import csv
from itertools import groupby
from operator import itemgetter

with open("20201001.csv", 'r', encoding="ASCII", newline="") as file:
    all_rows = csv.reader(file, delimiter = ';')

    for file_index, rows in groupby(all_rows, itemgetter(0)):
        if file_index == '1':
            print(file_index, list(rows))


    with open("20201001_QLEDC12590.csv", 'w', encoding="ASCII", newline="") as new_file:
        csv_writer = csv.writer(new_file, delimiter = '\t')
        csv_writer.writerows(list(rows))
Viel mehr habe ich leider nicht geschafft :( wobei ich sehr viel auch ausprobiert habe.

Vielen Dank für die Hilfe
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@yourself: Warum musst Du eine Gruppe auswählen? Ich dachte Du wolltest alle Gruppen in neue Dateien speichern? Dann musst Du nichts auswählen, Du bekommst die Gruppen ja bereits, Du müsstest sie halt abspeichern. An der Stelle wo Du sie bekommst.

Da wo der Speicherversuch jetzt steht, ist er offensichtlich falsch, denn dort hat `rows` den Wert vom letzten Schleifendurchlauf, und damit sehr wahrscheinlich nicht mehr den wo die erste Spalte den Wert 1 hat. In dem Fall hättest Du sogar noch ein zweites Problem weil `rows` ein Iterator ist, und der in der Schleife schon durchlaufen und damit ”gelehrt” wurde.

Der `list()`-Aufruf bei `writerows()` ist unnötig. Der wurde beim `print()` ja nur gebraucht um den Iterator als Liste zu realisieren, damit man die Werte ausgeben kann, und nicht den Iterator selbst.

Du musst die Dateien *in* der Schleife erzeugen/schreiben. Und falls sich der Dateiname aus dem Ursprungsdateinamen und dem Wert in der ersten Spalte bildet, dann muss Du Code schreiben der genau das tut. Hilfreich ist da das `pathlib`-Modul. Und f-Zeichenkettenliterale und/oder die `format()`-Methode auf Zeichenketten um den Wert in den Dateinamen zu bekommen. Wenn der mit führenden 0-en aufgefüllt werden soll, macht es vielleicht auch Sinn den Wert zwischendurch mal in eine Zahl umzuwandlen.

Und es wird IMHO schon komplex genug um das ganze in Funktionen aufzuteilen, damit Du Teilprobleme jeweils mit einer Funktion lösen kannst, die Du unabhängig vom Rest entwickeln und testen kannst. Auch wenn man dann am Ende doch wieder alles in eine Hauptfunktion integriert, ist es beim Entwickeln sicher hilfreich nicht immer das gesamte Programm laufen zu lassen um zu testen ob eine Teillösung richtig funktioniert.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
yourself
User
Beiträge: 6
Registriert: Montag 27. September 2021, 12:52

Habs hinbekommen. Vielen Dank :)
Antworten