get_dummies error de memoria python

Tengo un problema con un conjunto de datos que tiene 400,000 filas y 300 variables. Tengo que obtener variables ficticias para una variable categórica con más de 3,000 elementos diferentes. Al final, quiero terminar con un conjunto de datos con 3,300 variables o características para poder entrenar un modelo de RandomForest.

Esto es lo que he tratado de hacer:

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

Cuando hago eso siempre me sale un error de memoria. ¿Hay un límite para la cantidad de variables que puedo tener?

Si hago eso solo con las primeras 1,000 filas (que tienen 374 categorías diferentes), simplemente funciona bien.

¿Alguien tiene una solución para mi problema? La computadora que estoy usando tiene 8 GB de memoria.

Actualización: A partir de la versión 0.19.0, get_dummies devuelve un entero de 8 bits en lugar de una flotación de 64 bits, lo que solucionará este problema en muchos casos y hará que la as_type solución as_type innecesaria. Ver: get_dummies – pandas 0.19.0

Pero en otros casos, la opción sparse describe a continuación puede ser útil.

Respuesta original: Aquí hay un par de posibilidades para probar. Ambos reducirán sustancialmente la huella de memoria del dataframe, pero aún podría tener problemas de memoria más adelante. Es difícil de predecir, solo tendrás que intentarlo.

(tenga en cuenta que estoy simplificando la salida de info() continuación)

 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 

Aquí está nuestra línea de base. Cada columna ficticia ocupa 800 bytes porque los datos de muestra tienen 100 filas y parece que get_dummies por defecto float64 (8 bytes). Esto parece una forma innecesariamente ineficiente de almacenar los maniquíes, ya que podría usar tan poco como un poco para hacerlo, pero puede haber alguna razón para eso que no conozco.

Entonces, primero intente, simplemente cambie a un entero de un byte (esto no parece ser una opción para get_dummies por lo que debe hacerse como una conversión con astype(np.int8) .

 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 

Cada columna ficticia ahora ocupa 1/8 de la memoria como antes.

Alternativamente, puede usar la opción sparse de get_dummies .

 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 

Ahorros bastante comparables. La info() esconde un poco la forma en que se producen los ahorros, pero puede ver el valor del uso de la memoria para ver los ahorros totales.

Cuál de estos funcionará mejor en la práctica dependerá de sus datos, por lo que solo tendrá que probarlos (o incluso podría combinarlos).