KitKat::new() schrieb:
Das kann nur der OP beantworten. In Post #1 schrieb er von 25 vs. 77 MB, von daher dann kann diese Näherung hinhauen oder auch nicht.
KitKat::new() schrieb:
Einmal O(nlogn) fuers sortieren, und einmal fuers durchiterieren + passenden Eintrag finden
O(nlogn)+O(nlogn) = O(nlogn)
O(n2 log-n2) fürs in-place Sortieren von B
O(n1) fürs Durchiterieren über alle Zeilen von A (das Auffinden in B ist dann, bei sortiertem B, konstant)
macht: O(n2 log-n2 n1)
KitKat::new() schrieb:
Die einsen (bzw. die noetigen Infos zur Identifizierung) in B in eine Hashmap packen
Aber das Erstellen der Hashmap für B kostet ja auch was!
Wenn ich einen neuen Container erstelle und die Elemente einfach 1:1 rüberkopiere, dann wäre die Komplexität O(n2) fürs Kopieren plus der overhead für das memory-management des neuen Containers. Für die Hashmap ist das Finden der Position für get/put O(1) (bester Fall) bis O(n2) (worst case); selbst im Idealfall landen wir damit nach wie vor noch bei O(n2) plus eben dem ganzen memory-management overhead. Und da die Hashmap eher viele memory-chunks alloziieren werden wird und memory allocation per se nicht billig ist, kann man den ganzen overhead nicht vernachlässigen.
Bei in-place Sortierung, also die Elemente in einem bestehenden Container umsortieren, ist die Komplexität O(n2 log-n2), dafür fällt der memory-management overhead weg. Und je nach Programmiersprache und Verfügbarkeit von einem move-constructor (wie in C++) können die einzelnen Verschiebeoperationen auch deutlich billiger sein als Kopieroperationen in einen neuen Container. Das führt aber schon sehr ins Detail und lässt sich schwer verallgemeinern.
KitKat::new() schrieb:
Noch besser waere nicht einzeilen-Strings zu verwenden, sondern die Datei in einem Rutsch zu lesen und dann zeilenweise drueberzuscannen (und Strings erst bei Bedarf zu erstellen), aber das haut wahrscheinlich nicht hin mit R.
In R kann man schon den ganzen Dateiinhalt als einen einzigen string einlesen und nachher parsen. Dieses Parsen von einem Riesen-string würde aber in R ziemlich lästig/kompliziert werden.
Die "natürlichste" R-Lösung wäre, zuerst alle Zeilen einzulesen
(readLines)
und dann eine der Regex-Operationen (z.B.
sub
) vektorisiert über diese Zeilen loszulassen um die Strings in zeilenweises "Rest" und Passed zu splitten.
Bzgl. eines korrekt funktionierenden Programms ist die Hauptschwierigkeit, überhaupt die CSV-Struktur der Daten ausreichend zu berücksichtigen, inklusive der möglichen Sonderfälle. Ein Feld kann z.B. selbst Kommas beinhalten, wie in:
Code:
ID,Value,Text
102,3.141,"This is quoted text which, unfortunately, contains itself comma characters"
Man kann also nicht einfach pauschal beim n-ten Komma den string splitten. Und da Text-Felder natürlich auch wiederum selbst quotation-characters als Textelemente enthalten können, wie in:
Code:
ID,Value,Text
102,3.141,"This is quoted text which, unfortunately, mentions ""Mister X"" as quoted person"
muss man beim parsen von quotes auch das wieder berücksichtigen.
Wie sehr das ein Problem ist oder nicht hängt natürlich sehr von der Struktur der tatsächlichen Datei ab (können solche Fälle vorkommen? Sind, wenn Textfelder quotiert werden, ALLE quotiert oder ev. nur ein paar, z.B. diejenigen die wegen darin enthaltenen Kommas die Quotierung zwingend brauchen)?
Und beim Rückschreiben der neuen CSV-Datei spielt sich dasselbe in Grün ab: Es ist nicht so leicht hier sicherzustellen, dass bis auf Feld "Passed" alle anderen Characters exakt dieselben sind wie in der Ursprungsdatei sind.
Man könnte das so angehen:
a) Einmal die Datei als CSV-Einlesen -> die Spalten werden nun automatisch nach dem korrekten Komma gesplittet, aber aufgrund von Interpretation von Sonderzeichen stimmt der character-Inhalt der einzelnen gelesenen Felder ev. NICHT mehr mit der ursprünglichen character-Sequenz der entsprechenden Felder in der Rohdatei überein.
b) pro Zeile abzählen, wieviele Kommas insgesamt in Feldern vor und nach der Zielspalte (hier: "Passed") vorkommen - solche Kommas können z.B. wie oben illustriert in Textelementen vorkommen
c) Die Datei neu einlesen, diesmal zeilenweise als reiner (uninterpretierter) Text, und nun die Info aus b) nutzen um pro Zeile gezielt Spalte "Passed" rauszuextrahieren und den String vor/nach dieser Spalte exakt so zu belassen wie er ist (inklusive Sonderzeichen und Spalten-separatoren)
d) Daten matchen und bei Bedarf ersetzen, und die Felder aus c) zusammen mit dem aktualisierten "Passed"-Wert und ein Komma als Separator vor&nach dem Passed-Wert rausschreiben.