73 votes

Pandas read_csv dtype lire toutes les colonnes mais peu comme chaîne de caractères

J'utilise Pandas pour lire un certain nombre de CSV. Je passe un paramètre options json to dtype pour indiquer à Pandas les colonnes à lire en tant que chaîne au lieu de la valeur par défaut :

dtype_dic= { 'service_id':str, 'end_date':str, ... }
feedArray = pd.read_csv(feedfile , dtype = dtype_dic)

Dans mon scénario, tous les colonnes, à l'exception de quelques unes spécifiques, doivent être lues comme des chaînes de caractères. Ainsi, au lieu de définir plusieurs colonnes comme str dans dtype_dic J'aimerais définir seulement les quelques éléments que j'ai choisis comme int ou float. Existe-t-il un moyen de le faire ?

Il s'agit d'une boucle parcourant plusieurs CSV avec des colonnes différentes, donc une conversion directe de colonne après avoir lu le csv entier comme chaîne ( dtype=str ), ne serait pas facile car je ne saurais pas immédiatement quelles sont les colonnes de ce csv. (Je préférerais consacrer cet effort à la définition de toutes les colonnes dans le dtype json).

Edit : Mais s'il y a un moyen de traiter la liste des noms de colonnes à convertir en nombre sans se tromper si cette colonne n'est pas présente dans ce csv, alors oui ce sera une solution valide, s'il n'y a pas d'autre moyen de le faire à l'étape de lecture du csv lui-même.

Note : cela semble comme une question déjà posée mais les réponses à cette question étaient très différentes (liées aux bools) et ne s'appliquent pas à cette question. S'il vous plaît ne pas marquer comme un double !

113voto

Nathan Points 1050

EDIT - désolé, j'ai mal lu votre question. J'ai mis à jour ma réponse.

Vous pouvez lire l'ensemble du csv sous forme de chaînes de caractères, puis convertir les colonnes souhaitées en d'autres types, comme ceci :

df = pd.read_csv('/path/to/file.csv', dtype=str)
# example df; yours will be from pd.read_csv() above
df = pd.DataFrame({'A': ['1', '3', '5'], 'B': ['2', '4', '6'], 'C': ['x', 'y', 'z']})
types_dict = {'A': int, 'B': float}
for col, col_type in types_dict.items():
    df[col] = df[col].astype(col_type)

Une autre approche, si vous voulez vraiment spécifier les types appropriés pour toutes les colonnes lors de la lecture du fichier et ne pas les modifier par la suite : lisez seulement les noms des colonnes (pas les lignes), puis utilisez-les pour indiquer les colonnes qui doivent être des chaînes de caractères.

col_names = pd.read_csv('file.csv', nrows=0).columns
types_dict = {'A': int, 'B': float}
types_dict.update({col: str for col in col_names if col not in types_dict})
pd.read_csv('file.csv', dtype=types_dict)

0 votes

1. Une erreur sera commise si les colonnes en question ne sont pas présentes dans le CSV. Veuillez consulter la question. 2. Je veux que par défaut TOUTES les colonnes soient des chaînes de caractères, à l'exception de certaines choisies. Voir la question.

0 votes

Génial ! Désolé de ne pas avoir vu ta mise à jour à l'époque c'est drôle, je pensais être alerté si quelque chose changeait. J'aime particulièrement la deuxième approche le meilleur des deux mondes.

0 votes

Cela ne fonctionnerait pas si vous voulez spécifier un séparateur décimal dans la fonction read_csv. Ces nombres seront convertis en str avec le mauvais séparateur décimal et vous ne pourrez pas les convertir directement en float.

21voto

Muhammet Coskun Points 371

J'ai récemment rencontré le même problème, bien que je n'aie qu'un seul fichier csv et que je n'aie pas besoin de boucler sur les fichiers. Je pense que cette solution peut également être adaptée en boucle.

Je présente ici une solution que j'ai utilisée. Les pandas read_csv a un paramètre appelé converters qui prévaut sur dtype afin que vous puissiez profiter de cette fonctionnalité.

Un exemple de code est le suivant : Supposons que notre data.csv contient toutes les colonnes float64 sauf A y B qui sont des colonnes de type chaîne. Vous pouvez lire ce fichier en utilisant :

df = pd.read_csv('data.csv', dtype = 'float64', converters = {'A': str, 'B': str})  

Le code signale que les convertisseurs remplacent les dtypes pour ces deux colonnes A et B, et le résultat est conforme à ce qui est souhaité.

Pour ce qui est de boucler sur plusieurs fichiers csv, il suffit de déterminer quelles colonnes seront des exceptions à mettre dans les convertisseurs. C'est facile si les fichiers ont un modèle similaire de noms de colonnes, sinon, cela deviendrait fastidieux.

1voto

Shady Smaoui Points 69

Vous pouvez procéder comme suit :

pd.read_csv(self._LOCAL_FILE_PATH,
            index_col=0,
             encoding="utf-8",
             dtype={
                    'customer_id': 'int32',
                    'product_id': 'int32',
                    'subcategory_id': 'int16',
                    'category_id': 'int16',
                    'gender': 'int8',
                    'views': 'int8',
                    'purchased': 'int8',
                    'added': 'int8',
                    'time_on_page': 'float16',
                 })

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X