2015-07-09 20 views
7

i relativly neu in Python, und ich habe ein kleines Problem mit einem Datensatz. Der Datensatz hat 400.000 Zeilen und 300 Variablen. Ich muss Dummy-Variablen für eine kategoriale Variable mit mehr als 3000 verschiedenen Elementen erhalten. Am Ende möchte ich einen Datensatz mit 3300 Variablen oder Features haben, damit ich das RandomForest-Modell trainieren kann. Hierget_dummies Python Speicherfehler

ist, was ich zu tun versucht:

df = pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1) 

Wenn ich tun, dass ich immer einen Speicherfehler bekommen. Gibt es eine Grenze für die Anzahl der Variablen, die ich haben kann?

Wenn ich das mit nur die ersten 1000 Zeilen (die 374 verschiedenen Kategorien bekam) es funktioniert einfach Finne.

Hat jemand eine Lösung für mein Problem?

Die Maschine Ich benutze ist ein Intel I7 mit 8 GB Ram.

Sie

+0

32-Bit- oder 64-Bit-Python? Das Limit ist die Heap-Größe der Python-Implementierung, bei der es sich um einen Bereich des virtuellen Speichers und nicht um RAM handelt. Verschiedene Versionen und verschiedene Implementierungen auf verschiedenen Betriebssystemen haben unterschiedliche Einschränkungen.Offensichtlich hast du einen getroffen. Müssen Sie all diese Daten gleichzeitig im virtuellen Speicher ablegen? – cdarke

+0

Ich verwende 64-Bit-Python. Was wäre die Lösung dafür? Dass ich den Datensatz in mehrere Teile teile und meine Arbeit an diesen verschiedenen Teilen mache? – Duesentrieb

+0

OK, ich würde vorschlagen, dass wenn Sie auf 32-Bit waren. In diesem Fall müssen Sie Ihr Design erneut besuchen. – cdarke

Antwort

18

Update danken: Beginnend mit 0.19.0 Version, get_dummies gibt eine ganze Zahl 8bit statt 64-Bit-Float, die dieses Problem in vielen Fällen beheben. Siehe: get_dummies -- pandas 0.19.0

Hier ein paar Möglichkeiten, um zu versuchen sind. Beides reduziert den Speicherbedarf des Datenrahmens erheblich, aber Sie könnten später immer noch Probleme mit dem Arbeitsspeicher bekommen. Es ist schwer vorherzusagen, du musst es nur versuchen.

(beachten Sie, dass ich die Ausgabe von info() unten bin vereinfacht)

df = pd.DataFrame({ 'itemID': np.random.randint(1,4,100) }) 

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null float64 
itemID__2 100 non-null float64 
itemID__3 100 non-null float64 

memory usage: 3.5 KB 

Hier ist unsere Basislinie. Jede Dummy-Spalte belegt 800 Byte, da die Beispieldaten 100 Zeilen haben und get_dummies standardmäßig auf float64 (8 Byte) festgelegt ist. Dies scheint eine unnötig ineffiziente Möglichkeit zu sein, Dummies zu speichern, da man so wenig wie möglich dafür verwenden kann, aber es gibt vielleicht einen Grund für das, was mir nicht bewusst ist.

Also, erster Versuch, ändern Sie einfach auf eine Ein-Byte-Ganzzahl (dies keine Option für get_dummies zu sein scheint es als eine Konvertierung mit astype(np.int8) getan werden, damit hat.

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_').astype(np.int8)], 
           axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null int8 
itemID__2 100 non-null int8 
itemID__3 100 non-null int8 

memory usage: 1.5 KB 

Jede Dummy-Spalte nimmt jetzt 1/8 der Speicher als zuvor.

Alternativ können Sie die sparse Möglichkeit get_dummies verwenden können.

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_',sparse=True)], 
           axis=1).info() 

itemID  100 non-null int32 
itemID__1 100 non-null float64 
itemID__2 100 non-null float64 
itemID__3 100 non-null float64 

memory usage: 2.0 KB 

Ziemlich vergleichbare Einsparungen. Die Ausgabe info() verbirgt etwas die Art und Weise, wie Einsparungen auftreten, aber Sie können den Wert der Speichernutzung betrachten, um die Gesamteinsparungen zu sehen.

Es ist schwer, welche davon zu sagen, in der Praxis besser funktionieren wird (wenn entweder eine praktische Lösung überhaupt ist), so dass Sie müssen sie nur jeweils einen Versuch geben. Theoretisch könnte man die beiden Ansätze sogar kombinieren, aber ich würde nicht versuchen, es sei denn, es stellt sich heraus, dass jeder Ansatz für sich selbst funktioniert.

+0

Vielen Dank. Ich habe den Datentyp in Integer geändert und es funktioniert! – Duesentrieb