Python: Zusammenfassen großer Listen

OP #3061002
Lesenswert?
• ▲
▼
Hallo zusammen,

ich habe eine sehr lange Liste (> 20.000 Zeilen aus CSV-Datei) der Form:
[10, 1, 1]
[12, 0, 36]
[14, 60, 69]
[16, 0, 42]
[18, 0, 17]
[10, 7, 5]
[12, 14, 8]
...

Dies wiederholt sich mit verschiedenen Werten. Was ich jetzt benötige 
ist eine Zusammenfassung von den Zeilen zu einer Zeile unter der 
Vorraussetzung, dass die Werte der Spalte 1 eindeutig sind.

Anders formuliert: Mache aus der Liste oben die folgende Zeile:
[10, 1, 1, 12, 0, 36, 14, 60, 69, 18, 0, 17]

Im Endeffekt muss ich mir fünf Zeilen nehmen, gucken ob in der ersten 
Spalte die Zahlen 10 bis 18 vorkommen und wenn ja diese in eine neue 
Liste kopieren mit neueListe.append(alteListe[0], alteListe[1], ...). 
Anschließend kommen die nächsten fünf Zeilen.

Nun habe ich verschiedene Probleme: Zum Einen kann es vorkommen, dass 
z.B. die 12 zwei mal hintereinander vorkommt. Zum Anderen: wie kann ich 
abfragen wann ich die alte Liste vollständig abgearbeitet habe?

Ich hoffe auf eure Hilfe!

Gruß
Dennis
Gast #3061042
Lesenswert?
• ▲
▼
Hi,

Dennis S. schrieb:
> ich habe eine sehr lange Liste (> 20.000 Zeilen aus CSV-Datei) der Form:
> [10, 1, 1]
> [12, 0, 36]
> [14, 60, 69]
> [16, 0, 42]
> [18, 0, 17]
> [10, 7, 5]
> [12, 14, 8]
> ...
>
> Dies wiederholt sich mit verschiedenen Werten. Was ich jetzt benötige
> ist eine Zusammenfassung von den Zeilen zu einer Zeile unter der
> Vorraussetzung, dass die Werte der Spalte 1 eindeutig sind.
>
> Anders formuliert: Mache aus der Liste oben die folgende Zeile:
> [10, 1, 1, 12, 0, 36, 14, 60, 69, 18, 0, 17]

Wo bleiben die Zeilen [10, 7, 5] und [12, 14, 8]?

Vielleicht was in die Richtung?
1
d = dict()
2
for line in csv:
3
  if line[0] not in d.keys(): d[line[0]] = list()
4
  d[line[0]] += line

Ach ja: Python ist ziemlich flott. 20k Zeilen sind auf einem halbwegs 
aktüllen Rechner eher pillepalle.

LG,
Klaus
OP #3061064
Lesenswert?
• ▲
▼
Klaus Maus schrieb:
> Wo bleiben die Zeilen [10, 7, 5] und [12, 14, 8]?
Die werden in die nächste Zeile geschmissen
[10, 1, 1, 12, 0, 36, 14, 60, 69, 18, 0, 17],
[10, 7, 5, 12, 14, 8, ....]

> Vielleicht was in die Richtung?
Gute Idee, schaue ich mir mal genauer an!

> Ach ja: Python ist ziemlich flott. 20k Zeilen sind auf einem halbwegs
> aktüllen Rechner eher pillepalle.
Damit wollte ich auch nur den Vorschlag ausschließen, das händisch zu 
machen! ;-)

Gruß Dennis
OP #3061121
Lesenswert?
• ▲
▼
Der Beitrag von Klaus war schon recht hilfreich, aber ich versuche es 
nochmals zu formulieren:

Ich nenne die erste Spalte jetzt "ID". Es könnten die ID 10, 12, 14, 16 
und 18 auftreten, jedoch nicht zwangsläufig in der Reihenfolge und / 
oder gleich häufig (d.h. doppeltes Auftreten direkt hintereinander ist 
möglich, fehlen auch jedoch selten).

Grundsätzliches Ziel ist es eine Liste folgender Art zu bekommen:

1. Zeile beinhaltet das erste Auftreten aller ID inkl. "Daten"
2. Zeile beinhaltet das zweite Auftreten aller ID inkl. "Daten"
3. Zeile beinhaltet das dritte Auftreten aller ID inkl. "Daten"

Jedoch soll erst eine neue Zeile "angefangen" werden, wenn das Set 
komplett ist. Kommt also die Zeile mit der ID 12 zweimal vor, so wird 
das erste oder zweite Vorkommen (unwichtig) ignoriert und zunächst nach 
der 14 gesucht.

Sollte eine ID fehlen (bspw. die 14) soll das komplette Set verworfen 
werden.

"Startpunkt" des Algorithmus soll die ID 10 sein. Also etwas in die 
Richtung wie:
wenn ID = 10 dann füge Daten zur Liste hinzu,
wenn ID = 12 und ID 10 bereits in Liste, füge Daten von ID 12 hinzu,
wenn ID = 14 und ID 14 bereits in Liste, füge Daten von ID 14 hinzu,
...


Ist das verständlicher?

Gruß
Dennis
Gast #3061818
Lesenswert?
• ▲
▼
Tut das was du willst? (wenn Reihenfolge der IDs z.b. 10,14,12, ... ist 
wird die 14 ignoriert, da die 12 vorher fehlt. Richtig so?
1
def transform(lines, ids = [10,12,14,16,18]):
2
    "<addWhatItreallymeansHere> lines = input, ids = list of the occurring IDs (in order)"
3
    res = []
4
    id_index = 0
5
    for line in lines:
6
        if line[0] == ids[id_index]:
7
            res += line
8
        id_index += 1
9
        if id_index == len(ids)-1:
10
            yield res
11
            res = []
12
            id_index = 0
Da ich nicht weiß wie fit du in Python bist: das ist ein Generator, 
falls du wirklich eine Liste brauchst kannst du z.b. einfach 
list(transform(liste)) schreiben. Und tu dir den Gefallen und setze 
einen vernünftigen Funktionsnamen, transform heißt die nur weil ich 
keine Ahnung habe was sie eigentlich tun soll.
OP #3062294
Lesenswert?
• ▲
▼
Hallo adsf,

vielen Dank schon mal! Ich habe in der Tat sehr wenig Python-Erfahrung 
und das Thema Generatoren ist mir völlig unbekannt...

Ich habe jetzt den Code von dir an den Kopf meiner Quelldatei gepastet. 
Den Aufruf mache ich wie ich es häufiger im Netz gefunden habe mit

for n in transform(dataSet):
    print n

Leider kommt keine Ausgabe... Was habe ich übersehen?

Gruß Dennis
OP #3062339
Lesenswert?
• ▲
▼
Mein Ansatz scheint zu funktionieren, ist aber vermutlich sehr dreckig 
programmiert..
1
new = []
2
print("!> Clustering data...")
3
maxData = len(dataSet) / 5 * 5
4
for n in range(0, maxData - 1):
5
    #print n
6
    if dataSet[n][2]    == 10 and \
7
       dataSet[n+1][2]  == 12 and \
8
       dataSet[n+2][2]  == 14 and \
9
       dataSet[n+3][2]  == 16 and \
10
       dataSet[n+4][2]  == 18:
11
        new.append([dataSet[n],  \
12
                        dataSet[n+1], \
13
                        dataSet[n+2], \
14
                        dataSet[n+3], \
15
                        dataSet[n+4]])
16
    else: continue
17

18
# create an additional file for debugging
19
with open("tmp_" + inputFile, 'wb') as f:
20
    writer = csv.writer(f, delimiter = delimOutput)
21
    writer.writerows(new)

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.