txt tablas seleccionar recorrer notebook leer importar graficar documentacion datos data con como columnas cargar archivos python numpy pandas multiple-columns categories

tablas - Python Pandas-Cambiando algunos tipos de columnas a categorías



seleccionar columnas de un dataframe pandas (4)

He introducido el siguiente archivo CSV en iPython Notebook:

public = pd.read_csv("categories.csv") public

También he importado pandas como pd, numpy como np y matplotlib.pyplot como plt. Los siguientes tipos de datos están presentes (el siguiente es un resumen: hay alrededor de 100 columnas)

In [36]: public.dtypes Out[37]: parks object playgrounds object sports object roading object resident int64 children int64

Quiero cambiar ''parques'', ''patios de recreo'', ''deportes'' y ''recorridos'' a categorías (tienen respuestas de escala de Likert en ellas, aunque cada columna tiene diferentes tipos de respuestas de Likert (por ejemplo, una está "muy de acuerdo", "de acuerdo "etc., otro tiene" muy importante "," importante ", etc.), dejando el resto como int64.

Pude crear un marco de datos separado - public1 - y cambiar una de las columnas a un tipo de categoría usando el siguiente código:

public1 = {''parks'': public.parks} public1 = public1[''parks''].astype(''category'')

Sin embargo, cuando intenté cambiar un número a la vez usando este código, no tuve éxito:

public1 = {''parks'': public.parks, ''playgrounds'': public.parks} public1 = public1[''parks'', ''playgrounds''].astype(''category'')

A pesar de esto, no quiero crear un marco de datos separado con solo las columnas de categorías. Me gustaría cambiarlos en el marco de datos original.

Intenté varias formas de lograr esto, luego probé el código aquí: Pandas: cambiar el tipo de datos de las columnas ...

public[[''parks'', ''playgrounds'', ''sports'', ''roading'']] = public[[''parks'', ''playgrounds'', ''sports'', ''roading'']].astype(''category'')

y obtuve el siguiente error:

NotImplementedError: > 1 ndim Categorical are not supported at this time

¿Hay alguna manera de cambiar los ''parques'', ''patios de recreo'', ''deportes'', ''rodar'' a categorías (para que luego se puedan analizar las respuestas a escala de Likert), dejando ''residente'' e ''niños'' (y las otras 94 columnas que son cuerdas, int + flotadores) intactos por favor? O, ¿hay una mejor manera de hacer esto? Si alguien tiene alguna sugerencia y / o retroalimentación, estaría muy agradecido ... ¡Me estoy quedando calvo lentamente arrancando mi cabello!

Muchas gracias de antemano.

Editado para agregar - Estoy usando Python 2.7.


A partir de pandas 0.19.0, What''s New describe que read_csv admite el análisis de columnas Categorical directamente. Esta respuesta se aplica solo si está comenzando desde read_csv , de lo contrario, creo que la respuesta de unutbu sigue siendo la mejor. Ejemplo en 10,000 registros:

import pandas as pd import numpy as np # Generate random data, four category-like columns, two int columns N=10000 categories = pd.DataFrame({ ''parks'' : np.random.choice([''strongly agree'',''agree'', ''disagree''], size=N), ''playgrounds'' : np.random.choice([''strongly agree'',''agree'', ''disagree''], size=N), ''sports'' : np.random.choice([''important'', ''very important'', ''not important''], size=N), ''roading'' : np.random.choice([''important'', ''very important'', ''not important''], size=N), ''resident'' : np.random.choice([1, 2, 3], size=N), ''children'' : np.random.choice([0, 1, 2, 3], size=N) }) categories.to_csv(''categories_large.csv'', index=False)

<0.19.0 (o> = 19.0 sin especificar el tipo de dtype)

pd.read_csv(''categories_large.csv'').dtypes # inspect default dtypes children int64 parks object playgrounds object resident int64 roading object sports object dtype: object

> = 0.19.0

dtypes análisis de dtypes mixtos como Categorical se puede implementar pasando un diccionario dtype={''colname'' : ''category'', ...} en read_csv .

pd.read_csv(''categories_large.csv'', dtype={''parks'': ''category'', ''playgrounds'': ''category'', ''sports'': ''category'', ''roading'': ''category''}).dtypes children int64 parks category playgrounds category resident int64 roading category sports category dtype: object

Actuación

Un ligero aumento de velocidad (cuaderno local de jupyter), como se menciona en las notas de la versión.

# unutbu''s answer %%timeit public = pd.read_csv(''categories_large.csv'') for col in [''parks'', ''playgrounds'', ''sports'', ''roading'']: public[col] = public[col].astype(''category'') 10 loops, best of 3: 20.1 ms per loop # parsed during read_csv %%timeit category_cols = {item: ''category'' for item in [''parks'', ''playgrounds'', ''sports'', ''roading'']} public = pd.read_csv(''categories_large.csv'', dtype=category_cols) 100 loops, best of 3: 14.3 ms per loop


A veces, solo tienes que usar un bucle for:

for col in [''parks'', ''playgrounds'', ''sports'', ''roading'']: public[col] = public[col].astype(''category'')


Encontré que usar un bucle for funciona bien.

for col in [''col_variable_name_1'', ''col_variable_name_2'', ect..]: dataframe_name[col] = dataframe_name[col].astype(float)


Puedes usar el método pandas.DataFrame.apply junto con una expresión lambda para resolver esto. En tu ejemplo podrías usar

df[[''parks'', ''playgrounds'', ''sports'']].apply(lambda x: x.astype(''category''))

No conozco una forma de ejecutar esto en el lugar, así que normalmente terminaré con algo como esto:

df[df.select_dtypes([''object'']).columns] = df.select_dtypes([''object'']).apply(lambda x: x.astype(''category''))

Obviamente, puedes reemplazar .select_dtypes con nombres de columna explícitos si no quieres seleccionar todos los tipos de datos (aunque en tu ejemplo parece que querías todos los tipos de object ).