Écriture d'un DataFrame pandas dans un fichier CSV

716

J'ai une trame de données en pandas que je voudrais écrire dans un fichier CSV. Je fais cela en utilisant:

df.to_csv('out.csv')

Et obtenir l'erreur:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u03b1' in position 20: ordinal not in range(128)

Existe-t-il un moyen de contourner cela facilement (c'est-à-dire que j'ai des caractères Unicode dans ma trame de données)? Et existe-t-il un moyen d'écrire dans un fichier délimité par des tabulations au lieu d'un CSV en utilisant, par exemple, une méthode «to-tab» (qui, je pense, n'existe pas)?

user7289
la source

Réponses:

1046

Pour délimiter par un onglet, vous pouvez utiliser l' separgument de to_csv:

df.to_csv(file_name, sep='\t')

Pour utiliser un encodage spécifique (par exemple 'utf-8'), utilisez l' encodingargument:

df.to_csv(file_name, sep='\t', encoding='utf-8')
Andy Hayden
la source
32
J'ajouterais index=Falsede supprimer l'index.
Medhat
12
J'ai d'abord été confus quant à la façon dont j'ai trouvé une réponse à la question que j'avais déjà écrite il y a 7 ans.
Hayden
251

Lorsque vous stockez un DataFrameobjet dans un fichier csv à l'aide de la to_csvméthode, vous n'aurez probablement pas besoin de stocker les indices précédents de chaque ligne de l' DataFrameobjet.

Vous pouvez éviter cela en passant une Falsevaleur booléenne au indexparamètre.

Un peu comme:

df.to_csv(file_name, encoding='utf-8', index=False)

Donc, si votre objet DataFrame est quelque chose comme:

  Color  Number
0   red     22
1  blue     10

Le fichier csv stockera:

Color,Number
red,22
blue,10

au lieu de (le cas où la valeur par défaut a True été passée)

,Color,Number
0,red,22
1,blue,10
Sayan Sil
la source
Que faire si l'indexation est souhaitée, mais doit également avoir un titre? Utilisez-vous simplement df.rename_axis('index_name')? cela ne modifie pas le fichier lui
Zap
21

Pour écrire un DataFrame pandas dans un fichier CSV, vous aurez besoin DataFrame.to_csv. Cette fonction propose de nombreux arguments avec des valeurs par défaut raisonnables que vous devrez le plus souvent ignorer en fonction de votre cas d'utilisation spécifique. Par exemple, vous souhaiterez peut-être utiliser un séparateur différent, modifier le format datetime ou supprimer l'index lors de l'écriture. to_csvcontient des arguments que vous pouvez transmettre pour répondre à ces exigences.

Voici un tableau répertoriant certains scénarios courants d'écriture dans des fichiers CSV et les arguments correspondants que vous pouvez utiliser pour eux.

Écrivez à CSV ma dude

Notes de bas de page

  1. Le séparateur par défaut est supposé être une virgule ( ','). Ne changez pas cela sauf si vous savez que vous en avez besoin.
  2. Par défaut, l'index de dfest écrit comme première colonne. Si votre DataFrame n'a pas d'index (IOW, df.indexc'est la valeur par défaut RangeIndex), vous voudrez le définir index=Falselors de l'écriture. Pour expliquer cela d'une manière différente, si vos données ont un index, vous pouvez (et devriez) utiliser index=Trueou simplement le laisser complètement (comme par défaut True).
  3. Il serait judicieux de définir ce paramètre si vous écrivez des données de chaîne afin que d'autres applications sachent lire vos données. Cela permettra également d'éviter tout potentiel que UnicodeEncodeErrorvous pourriez rencontrer lors de l'enregistrement.
  4. La compression est recommandée si vous écrivez de gros DataFrames (> 100K lignes) sur le disque car cela entraînera des fichiers de sortie beaucoup plus petits. OTOH, cela signifie que le temps d'écriture augmentera (et par conséquent, le temps de lecture car le fichier devra être décompressé).
cs95
la source
18

Vous pouvez essayer autre chose si vous rencontrez des problèmes de codage en «utf-8» et que vous souhaitez passer cellule par cellule, vous pouvez essayer ce qui suit.

Python 2

(Où "df" est votre objet DataFrame.)

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = unicode(x.encode('utf-8','ignore'),errors ='ignore') if type(x) == unicode else unicode(str(x),errors='ignore')
            df.set_value(idx,column,x)
        except Exception:
            print 'encoding error: {0} {1}'.format(idx,column)
            df.set_value(idx,column,'')
            continue

Alors essaye:

df.to_csv(file_name)

Vous pouvez vérifier l'encodage des colonnes en:

for column in df.columns:
    print '{0} {1}'.format(str(type(df[column][0])),str(column))

Attention: errors = 'ignore' va juste omettre le caractère par exemple

IN: unicode('Regenexx\xae',errors='ignore')
OUT: u'Regenexx'

Python 3

for column in df.columns:
    for idx in df[column].index:
        x = df.get_value(idx,column)
        try:
            x = x if type(x) == str else str(x).encode('utf-8','ignore').decode('utf-8','ignore')
            df.set_value(idx,column,x)
        except Exception:
            print('encoding error: {0} {1}'.format(idx,column))
            df.set_value(idx,column,'')
            continue
Glen Thompson
la source
11

Parfois, vous rencontrez ces problèmes si vous spécifiez également le codage UTF-8. Je vous recommande de spécifier l'encodage lors de la lecture du fichier et le même encodage lors de l'écriture dans le fichier. Cela pourrait résoudre votre problème.

Harsha Komarraju
la source
7

Exemple d'exportation dans un fichier avec chemin complet sous Windows et dans le cas où votre fichier a des en- têtes :

df.to_csv (r'C:\Users\John\Desktop\export_dataframe.csv', index = None, header=True) 

Exemple si vous souhaitez stocker dans un dossier dans le même répertoire que votre script, avec l' encodage utf-8 et l' onglet comme séparateur :

df.to_csv(r'./export/dftocsv.csv', sep='\t', encoding='utf-8', header='true')
Harvey
la source
7

ce pourrait ne pas être la réponse pour ce cas, mais comme j'avais le même message d'erreur avec .to_csvj'ai essayé .toCSV('name.csv')et le message d'erreur était différent (" SparseDataFrame' object has no attribute 'toCSV'). Donc le problème a été résolu en transformant le dataframe en un dataframe dense

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Portefeuille Yury
la source
Vous avez eu l'erreur dans la seconde car elle ressemble à celle que vous avez utilisée .toCSVet non .to_csv. Vous avez oublié le trait de soulignement
Kyle C