Zapisywanie pand DataFrame do pliku CSV

713

Mam ramkę danych w pandach, którą chciałbym zapisać do pliku CSV. Robię to za pomocą:

df.to_csv('out.csv')

I pojawia się błąd:

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

Czy jest jakiś sposób na łatwe obejście tego problemu (tzn. W ramce danych mam znaki Unicode)? I czy istnieje sposób zapisu do pliku rozdzielanego tabulatorami zamiast CSV przy użyciu np. Metody „tab-tab” (której nie sądzę)?

użytkownik7289
źródło

Odpowiedzi:

1045

Aby oddzielić tabulatorem, możesz użyć separgumentu to_csv:

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

Aby użyć określonego kodowania (np. „Utf-8”), użyj encodingargumentu:

df.to_csv(file_name, sep='\t', encoding='utf-8')
Andy Hayden
źródło
32
Dodałbym, index=Falseaby upuścić indeks.
Medhat
11
Początkowo byłem zdezorientowany, jak znalazłem odpowiedź na pytanie, które napisałem już 7 lat temu.
Hayden
250

Podczas zapisywania DataFrameobiektu do pliku csv przy użyciu to_csvmetody, prawdopodobnie nie będzie potrzeby przechowywania poprzedzające indeksy każdego rzędu od DataFrameobiektu.

Można tego uniknąć , przekazując Falsewartość logiczną do indexparametru.

Trochę jak:

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

Więc jeśli obiekt DataFrame jest podobny do:

  Color  Number
0   red     22
1  blue     10

Plik csv będzie przechowywać:

Color,Number
red,22
blue,10

zamiast (w przypadku, gdy przekazano wartość domyślną True )

,Color,Number
0,red,22
1,blue,10
Sayan Sil
źródło
Co jeśli indeksowanie jest pożądane, ale powinno mieć również tytuł? Czy po prostu używasz df.rename_axis('index_name')? to nie zmienia samego pliku
Zap
19

Aby zapisać pand DataFrame w pliku CSV, będziesz potrzebować DataFrame.to_csv. Ta funkcja oferuje wiele argumentów z uzasadnionymi ustawieniami domyślnymi, które często trzeba zastąpić, aby dopasować je do konkretnego przypadku użycia. Na przykład możesz użyć innego separatora, zmienić format daty i godziny lub upuścić indeks podczas pisania. to_csvma argumenty, które możesz przekazać, aby spełnić te wymagania.

Oto tabela zawierająca niektóre typowe scenariusze zapisu do plików CSV i odpowiadające im argumenty, których możesz użyć.

Napisz do CSV ma koleś

Przypisy

  1. Domyślnym separatorem jest przecinek ( ','). Nie zmieniaj tego, chyba że wiesz, że musisz.
  2. Domyślnie indeks dfjest zapisywany jako pierwsza kolumna. Jeśli twoja DataFrame nie ma indeksu (IOW, df.indexjest to ustawienie domyślne RangeIndex), będziesz chciał ustawić index=Falsepodczas pisania. Aby wyjaśnić to w inny sposób, jeśli dane MASZĄ indeks, możesz (i powinieneś) go użyć index=Truelub po prostu całkowicie go pominąć (domyślnie jest True).
  3. Mądrze byłoby ustawić ten parametr, jeśli zapisujesz dane ciągu, aby inne aplikacje wiedziały, jak je odczytać. Pozwoli to również uniknąć potencjalnych UnicodeEncodeErrorproblemów, które możesz napotkać podczas zapisywania.
  4. Kompresja jest zalecana, jeśli piszesz duże ramki danych (> 100 000 wierszy) na dysk, ponieważ spowoduje to znacznie mniejsze pliki wyjściowe. OTOH, będzie to oznaczać, że czas zapisu wydłuży się (aw konsekwencji czas odczytu, ponieważ plik będzie musiał zostać zdekompresowany).
cs95
źródło
18

Jeśli masz problemy z kodowaniem do „utf-8” i chcesz przechodzić komórka po komórce, możesz spróbować czegoś innego.

Python 2

(Gdzie „df” to Twój obiekt 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

Więc spróbuj:

df.to_csv(file_name)

Możesz sprawdzić kodowanie kolumn przez:

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

Ostrzeżenie: błędy = „zignoruj” spowoduje po prostu pominięcie znaku, np

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
źródło
11

Czasami napotykasz te problemy, jeśli również określisz kodowanie UTF-8. Zalecam określenie kodowania podczas odczytu pliku i takiego samego kodowania podczas zapisu do pliku. To może rozwiązać twój problem.

Harsha Komarraju
źródło
7

Przykład eksportu do pliku z pełną ścieżką w systemie Windows oraz w przypadku, gdy plik ma nagłówki :

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

Przykład, jeśli chcesz przechowywać w folderze w tym samym katalogu, w którym znajduje się skrypt, z kodowaniem utf-8 i tabulatorem jako separatorem :

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

może nie być odpowiedzią na ten przypadek, ale ponieważ miałem ten sam komunikat o błędzie .to_csv, próbowałem, .toCSV('name.csv')a komunikat o błędzie był inny (" SparseDataFrame' object has no attribute 'toCSV'). Tak więc problem został rozwiązany przez przekształcenie ramki danych w gęstą ramkę danych

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Portfel Yury
źródło
Wystąpił błąd w drugim, ponieważ wygląda na to, że został użyty, .toCSVa nie .to_csv. Zapomniałeś podkreślenia
Kyle C