Schreiben eines Pandas DataFrame in eine CSV-Datei

715

Ich habe einen Datenrahmen in Pandas, den ich in eine CSV-Datei schreiben möchte. Ich mache das mit:

df.to_csv('out.csv')

Und den Fehler bekommen:

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

Gibt es eine Möglichkeit, dies einfach zu umgehen (dh ich habe Unicode-Zeichen in meinem Datenrahmen)? Und gibt es eine Möglichkeit, anstelle einer CSV-Datei in eine durch Tabulatoren getrennte Datei zu schreiben, z. B. mithilfe einer "to-tab" -Methode (von der ich glaube, dass sie nicht existiert)?

user7289
quelle

Antworten:

1045

Um durch eine Registerkarte abzugrenzen, können Sie das sepArgument verwenden to_csv:

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

Verwenden Sie das folgende encodingArgument, um eine bestimmte Codierung (z. B. 'utf-8') zu verwenden :

df.to_csv(file_name, sep='\t', encoding='utf-8')
Andy Hayden
quelle
32
Ich würde hinzufügen index=False, um den Index zu löschen.
Medhat
11
Ich war zunächst verwirrt darüber, wie ich eine Antwort auf die Frage fand, die ich bereits vor 7 Jahren geschrieben hatte.
Hayden
250

Wenn Sie ein DataFrameObjekt mit der Methode in einer CSV-Datei speichern to_csv, müssen Sie wahrscheinlich nicht die vorhergehenden Indizes jeder Zeile des DataFrameObjekts speichern .

Sie können dies vermeiden , indem Sie einen Falsebooleschen Wert an den indexParameter übergeben.

Etwas wie:

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

Wenn Ihr DataFrame-Objekt ungefähr so ​​aussieht:

  Color  Number
0   red     22
1  blue     10

In der CSV-Datei wird Folgendes gespeichert:

Color,Number
red,22
blue,10

statt (der Fall, als der Standardwert True übergeben wurde)

,Color,Number
0,red,22
1,blue,10
Sayan Sil
quelle
Was ist, wenn die Indizierung gewünscht wird, aber auch einen Titel haben sollte? Benutzt du nur df.rename_axis('index_name')? das ändert nichts an der Datei selbst
Zap
19

Um einen Pandas DataFrame in eine CSV-Datei zu schreiben, benötigen Sie DataFrame.to_csv. Diese Funktion bietet viele Argumente mit angemessenen Standardeinstellungen, die Sie häufig überschreiben müssen, um sie an Ihren spezifischen Anwendungsfall anzupassen. Beispielsweise möchten Sie möglicherweise ein anderes Trennzeichen verwenden, das Datum / Uhrzeit-Format ändern oder den Index beim Schreiben löschen. to_csvhat Argumente, die Sie übergeben können, um diese Anforderungen zu erfüllen.

In der folgenden Tabelle sind einige gängige Szenarien für das Schreiben in CSV-Dateien und die entsprechenden Argumente aufgeführt, die Sie für diese verwenden können.

Schreiben Sie an CSV ma dude

Fußnoten

  1. Das Standardtrennzeichen wird als Komma ( ',') angenommen. Ändern Sie dies nur, wenn Sie wissen, dass Sie es müssen.
  2. Standardmäßig wird der Index von dfals erste Spalte geschrieben. Wenn Ihr DataFrame keinen Index hat (IOW, dies df.indexist die Standardeinstellung RangeIndex), sollten Sie dies index=Falsebeim Schreiben festlegen . Um dies auf eine andere Weise zu erklären: Wenn Ihre Daten einen Index haben, können (und sollten) Sie ihn verwenden index=Trueoder einfach ganz weglassen (standardmäßig True).
  3. Es ist ratsam, diesen Parameter festzulegen, wenn Sie Zeichenfolgendaten schreiben, damit andere Anwendungen wissen, wie Ihre Daten gelesen werden. Dadurch werden auch potenzielle UnicodeEncodeErrorProbleme vermieden, die beim Speichern auftreten können.
  4. Die Komprimierung wird empfohlen, wenn Sie große DataFrames (> 100.000 Zeilen) auf die Festplatte schreiben, da dies zu viel kleineren Ausgabedateien führt. OTOH, dies bedeutet, dass sich die Schreibzeit erhöht (und folglich die Lesezeit, da die Datei dekomprimiert werden muss).
cs95
quelle
18

Etwas anderes können Sie versuchen, wenn Sie Probleme beim Codieren in 'utf-8' haben und Zelle für Zelle gehen möchten. Sie können Folgendes versuchen.

Python 2

(Wobei "df" Ihr DataFrame-Objekt ist.)

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

Dann versuche es:

df.to_csv(file_name)

Sie können die Codierung der Spalten überprüfen, indem Sie:

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

Warnung: error = 'ignore' lässt nur das Zeichen weg, z

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
quelle
11

Manchmal treten diese Probleme auf, wenn Sie auch die UTF-8-Codierung angeben. Ich empfehle Ihnen, die Codierung beim Lesen der Datei und dieselbe Codierung beim Schreiben in die Datei anzugeben. Dies könnte Ihr Problem lösen.

Harsha Komarraju
quelle
7

Beispiel für den Export in eine Datei mit vollständigem Pfad unter Windows und für den Fall, dass Ihre Datei Header enthält :

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

Beispiel, wenn Sie in einem Ordner in demselben Verzeichnis speichern möchten, in dem sich Ihr Skript befindet, mit utf-8-Codierung und Registerkarte als Trennzeichen :

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

Es konnte nicht die Antwort für diesen Fall sein, aber da ich die gleiche Fehlermeldung hatte, .to_csvversuchte ich es .toCSV('name.csv')und die Fehlermeldung war anders (" SparseDataFrame' object has no attribute 'toCSV'). Das Problem wurde also gelöst, indem der Datenrahmen in einen dichten Datenrahmen umgewandelt wurde

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Yury Wallet
quelle
Sie haben den Fehler im zweiten erhalten, da er so aussieht, als hätten Sie ihn verwendet .toCSVund nicht .to_csv. Sie haben den Unterstrich vergessen
Kyle C