2016-08-06 19 views
2

Ich habe ein Skript, das alle CSV-Dateien in einem Verzeichnis und verbindet sie nebeneinander, mit einem äußeren Join. Das Problem ist, dass mein Computer verschluckt (MemoryError), wenn ich versuche, es für die Dateien zu verwenden, die ich beitreten muss (ungefähr zwei Dutzend Dateien von jeweils 6-12 GB). Ich bin mir bewusst, dass Iertools verwendet werden können, um Loops effizienter zu machen, aber ich bin mir nicht sicher, ob und wie es auf diese Situation angewendet werden könnte. Die andere Alternative, an die ich denken kann, ist, mySQL zu installieren, die Grundlagen zu lernen und dies dort zu tun. Natürlich mache ich das lieber in Python, wenn es möglich ist, weil ich es bereits lerne. Eine R-basierte Lösung wäre ebenfalls akzeptabel.Effiziente Zusammenführung für viele große CSV-Dateien

Hier ist mein Code:

import os 
import glob 
import pandas as pd 
os.chdir("\\path\\containing\\files") 

files = glob.glob("*.csv") 
sdf = pd.read_csv(files[0], sep=',') 

for filename in files[1:]: 
    df = pd.read_csv(filename, sep=',') 
    sdf = pd.merge(sdf, df, how='outer', on=['Factor1', 'Factor2']) 

Ratschläge, wie dies auch mit Dateien zu tun groß für Speicher meines Computers würde sehr geschätzt werden.

Antwort

4

Verwenden , dass meiner Meinung nach würde sehr gut Ihre Bedürfnisse. Es handhabt auch out-of-core queries, also müssen Sie MemoryError nicht gegenüberstellen.

import os 
import glob 
import pandas as pd 
os.chdir("\\path\\containing\\files") 

files = glob.glob("*.csv") 
hdf_path = 'my_concatenated_file.h5' 

with pd.HDFStore(hdf_path, mode='w', complevel=5, complib='blosc') as store: 
    # This compresses the final file by 5 using blosc. You can avoid that or 
    # change it as per your needs. 
    for filename in files: 
     store.append('table_name', pd.read_csv(filename, sep=','), index=False) 
    # Then create the indexes, if you need it 
    store.create_table_index('table_name', columns=['Factor1', 'Factor2'], optlevel=9, kind='full') 
+1

, die eine Reihe von Fehlern warf, die erste war: 'Linie 2885, in run_code exec (code_obj, self.user_global_ns, self.user_ns)' – Thoughtcraft

+0

going csv -> hdf5 -> csv auf die Dateigrößen Sie ' Re Umgang mit wird einige Zeit dauern, ja? Ich würde versuchen, csv -> csv gehen, wenn ich könnte – Kosch

+0

Nicht wahr. HDF5 ist in meinen Tests mindestens 10 mal schneller als csv. Weiter erwähnt das OP nicht, dass die Ausgabe in csv sein sollte. Jede andere Implementierung wird einen ziemlich komplizierten Algorithmus mit Schleifen benötigen, da jede Datei, mit der OP zu tun hat, 6-12 GB groß ist. Wenn sich OP also nicht auf einem Supercomputer befindet, ist es schwierig, so viel RAM zu haben. – Kartik

0

Es besteht die Möglichkeit, dass dask für Sie geeignet ist. Es hängt möglicherweise davon ab, was Sie nach der Zusammenführung tun möchten.

+0

Ich werde es in einem einzigen großen csv speichern. – Thoughtcraft

0

Sie sollten in der Lage sein, dies mit Python zu tun, aber ich glaube nicht, das Lesen der CSVs sofort wird die effizienteste Nutzung Ihres Gedächtnisses sein.

How to read a CSV file from a stream and process each line as it is written?

+0

Ich bin mir nicht sicher, ob ich verstehe, wie der Stream funktioniert, aber ich denke, es könnte ein Problem sein, weil ich nicht einfach Zeilen miteinander verkette, sondern die Anwesenheit oder Abwesenheit desselben Schlüssels in verschiedenen Dateien ändert, wie die Zeilen ausgerichtet sein. – Thoughtcraft

+0

können Sie tun, was Sie wollen, solange es in den Speicher passt. Lies nur die benötigten Bits ein, wenn du sie benötigst, und spülere, was vollständig ist/mit der Festplatte übereinstimmt. – Kosch

Verwandte Themen