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ę)?

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')

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

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).

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

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.


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')

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')

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.