Menulis panda DataFrame ke file CSV

715

Saya memiliki dataframe dalam panda yang ingin saya tulis ke file CSV. Saya melakukan ini menggunakan:

df.to_csv('out.csv')

Dan mendapatkan kesalahan:

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

Apakah ada cara untuk menyiasatinya dengan mudah (yaitu saya memiliki karakter unicode dalam bingkai data saya)? Dan apakah ada cara untuk menulis ke file yang dibatasi tab daripada menggunakan CSV misalnya metode 'to-tab' (yang saya pikir tidak ada)?

pengguna7289
sumber

Jawaban:

1045

Untuk membatasi oleh tab Anda dapat menggunakan separgumen dari to_csv:

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

Untuk menggunakan penyandian khusus (mis. 'Utf-8') gunakan encodingargumen:

df.to_csv(file_name, sep='\t', encoding='utf-8')
Andy Hayden
sumber
32
Saya akan menambahkan index=Falseuntuk menjatuhkan indeks.
Medhat
11
Awalnya saya bingung bagaimana saya menemukan jawaban untuk pertanyaan yang sudah saya tulis 7 tahun lalu.
Hayden
251

Ketika Anda menyimpan DataFrameobjek ke dalam file csv dengan menggunakan to_csvmetode, Anda mungkin tidak akan perlu untuk menyimpan indeks sebelumnya masing-masing baris dari DataFrameobjek.

Anda dapat menghindari itu dengan mengirimkan Falsenilai boolean ke indexparameter.

Agak suka:

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

Jadi jika objek DataFrame Anda adalah sesuatu seperti:

  Color  Number
0   red     22
1  blue     10

File csv akan menyimpan:

Color,Number
red,22
blue,10

alih-alih (kasus ketika nilai default True disahkan)

,Color,Number
0,red,22
1,blue,10
Sayan Sil
sumber
Bagaimana jika pengindeksan diinginkan, tetapi juga harus memiliki judul? Apakah kamu hanya menggunakan df.rename_axis('index_name')? itu tidak mengubah file itu sendiri
Zap
20

Untuk menulis panda DataFrame ke file CSV, Anda perlu DataFrame.to_csv. Fungsi ini menawarkan banyak argumen dengan default yang masuk akal bahwa Anda akan lebih sering tidak perlu menimpa sesuai dengan kasus penggunaan spesifik Anda. Misalnya, Anda mungkin ingin menggunakan pemisah yang berbeda, mengubah format datetime, atau menjatuhkan indeks saat menulis. to_csvmemiliki argumen yang dapat Anda berikan untuk memenuhi persyaratan ini.

Berikut adalah tabel yang mencantumkan beberapa skenario umum penulisan ke file CSV dan argumen yang sesuai yang dapat Anda gunakan untuk mereka.

Menulis ke CSV ma dude

Catatan kaki

  1. Pemisah default dianggap koma ( ','). Jangan ubah ini kecuali Anda tahu harus melakukannya.
  2. Secara default, indeks dfditulis sebagai kolom pertama. Jika DataFrame Anda tidak memiliki indeks (TKI, itu df.indexadalah default RangeIndex), maka Anda akan ingin mengatur index=Falsesaat menulis. Untuk menjelaskan ini dengan cara yang berbeda, jika data Anda TIDAK memiliki indeks, Anda dapat (dan harus) menggunakan index=Trueatau membiarkannya sama sekali (karena standarnya True).
  3. Akan lebih bijaksana untuk mengatur parameter ini jika Anda menulis data string sehingga aplikasi lain tahu cara membaca data Anda. Ini juga akan menghindari potensi UnicodeEncodeErroryang mungkin Anda temui saat menyimpan.
  4. Kompresi disarankan jika Anda menulis DataFrames besar (> 100K baris) ke disk karena akan menghasilkan file output yang jauh lebih kecil. OTOH, itu berarti waktu menulis akan meningkat (dan akibatnya, waktu baca karena file perlu didekompresi).
cs95
sumber
18

Hal lain yang dapat Anda coba jika Anda mengalami masalah penyandian ke 'utf-8' dan ingin sel demi sel Anda dapat mencoba yang berikut ini.

Python 2

(Di mana "df" adalah objek DataFrame Anda.)

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

Lalu coba:

df.to_csv(file_name)

Anda dapat memeriksa penyandian kolom dengan:

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

Peringatan: kesalahan = 'abaikan' hanya akan menghilangkan karakter mis

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

Terkadang Anda menghadapi masalah ini jika Anda menentukan pengkodean UTF-8 juga. Saya sarankan Anda untuk menentukan penyandian saat membaca file dan penyandian yang sama saat menulis ke file. Ini bisa menyelesaikan masalah Anda.

Harsha Komarraju
sumber
7

Contoh ekspor dalam file dengan path lengkap pada Windows dan seandainya file Anda memiliki header :

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

Contoh jika Anda ingin menyimpan dalam folder di direktori yang sama dengan skrip Anda, dengan pengkodean utf-8 dan tab sebagai pemisah :

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

itu bisa bukan jawaban untuk kasus ini, tetapi karena saya memiliki pesan kesalahan yang sama dengan .to_csvsaya mencoba .toCSV('name.csv')dan pesan kesalahan berbeda (" SparseDataFrame' object has no attribute 'toCSV'). Jadi masalahnya diselesaikan dengan memutar kerangka data menjadi kerangka data padat

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')
Dompet Yury
sumber
Anda mendapatkan kesalahan pada yang kedua karena sepertinya Anda menggunakan .toCSVdan tidak .to_csv. Anda lupa garis bawah
Kyle C