J'ai introduit le fichier CSV suivant dans iPython Notebook:
public = pd.read_csv("categories.csv")
public
J'ai aussi importé des pandas en tant que pd, numpy en tant que np et matplotlib.pyplot en tant que plt. Les types de données suivants sont présents (le ci-dessous est un résumé - il y a environ 100 colonnes)
In [36]: public.dtypes
Out[37]: parks object
playgrounds object
sports object
roading object
resident int64
children int64
Je veux changer les catégories "parcs", "terrains de jeu", "sports" et "parcours" en catégories (elles ont des réponses à l'échelle de likert - chaque colonne contient différents types de réponses de type likert (par exemple, l'une est "tout à fait d'accord", "d'accord "etc., un autre a" très important "," important "etc.), le reste étant défini sur int64.
J'ai pu créer une image distincte - public1 - et modifier l'une des colonnes en un type de catégorie à l'aide du code suivant:
public1 = {'parks': public.parks}
public1 = public1['parks'].astype('category')
Cependant, lorsque j'ai essayé de changer un numéro à la fois en utilisant ce code, j'ai échoué:
public1 = {'parks': public.parks,
'playgrounds': public.parks}
public1 = public1['parks', 'playgrounds'].astype('category')
Malgré cela, je ne souhaite pas créer de cadre de données distinct avec uniquement les colonnes de catégories. Je voudrais qu'ils soient modifiés dans le cadre de données d'origine.
J'ai essayé de nombreuses façons pour y parvenir, puis le code ici: Pandas: changer le type de données des colonnes ...
public[['parks', 'playgrounds', 'sports', 'roading']] = public[['parks', 'playgrounds', 'sports', 'roading']].astype('category')
et a obtenu l'erreur suivante:
NotImplementedError: > 1 ndim Categorical are not supported at this time
Existe-t-il un moyen de changer les termes "parcs", "terrains de jeux", "sports", "parcours" en catégories (afin d'analyser les réponses à l'échelle de likert), en laissant "résidents" et "enfants" (et les 94 autres colonnes sont string, int + floats) intactes s'il vous plaît? Ou, y a-t-il une meilleure façon de faire cela? Si quelqu'un a des suggestions et/ou des commentaires, je vous en serais très reconnaissant ... je vais lentement devenir chauve en train de me déchirer les cheveux!
Merci d'avance.
édité pour ajouter - J'utilise Python 2.7.
Parfois, il suffit d'utiliser une boucle for:
for col in ['parks', 'playgrounds', 'sports', 'roading']:
public[col] = public[col].astype('category')
Vous pouvez utiliser la méthode pandas.DataFrame.apply
avec une expression lambda
pour résoudre ce problème. Dans votre exemple, vous pouvez utiliser
df[['parks', 'playgrounds', 'sports']].apply(lambda x: x.astype('category'))
Je ne connais pas de moyen d'exécuter ceci in-situ, donc je vais finir par avoir quelque chose comme ceci:
df[df.select_dtypes(['object']).columns] = df.select_dtypes(['object']).apply(lambda x: x.astype('category'))
Évidemment, vous pouvez remplacer .select_dtypes
par des noms de colonnes explicites si vous ne souhaitez pas sélectionner tous les types de données (bien que, dans votre exemple, il semble que vous vouliez tous les types object
).
Depuis pandas 0.19.0, What's New indique que read_csv
prend en charge l’analyse directe des colonnes Categorical
directement . Cette réponse ne s’applique que si vous démarrez à partir de read_csv
sinon, je pense que la réponse de unutbu est toujours préférable ... sur 10 000 enregistrements:
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)
pd.read_csv('categories_large.csv').dtypes # inspect default dtypes
children int64
parks object
playgrounds object
resident int64
roading object
sports object
dtype: object
Pour une analyse dtypes
mixte en tant que Categorical
, vous pouvez appliquer un dictionnaire dtype={'colname' : 'category', ...}
dans 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
Une légère accélération (carnet de notes local Jupyter), comme mentionné dans les notes de publication.
# 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
J'ai trouvé que l'utilisation d'une boucle for fonctionne bien.
for col in ['col_variable_name_1', 'col_variable_name_2', ect..]:
dataframe_name[col] = dataframe_name[col].astype(float)