Viết một DataFrame gấu trúc vào tệp CSV


715

Tôi có một khung dữ liệu trong gấu trúc mà tôi muốn ghi vào tệp CSV. Tôi đang làm điều này bằng cách sử dụng:

df.to_csv('out.csv')

Và nhận được lỗi:

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

Có cách nào để khắc phục điều này một cách dễ dàng (ví dụ: tôi có các ký tự unicode trong khung dữ liệu của mình) không? Và có cách nào để ghi vào tệp được phân tách bằng tab thay vì CSV bằng cách sử dụng phương thức 'to-tab' (mà tôi không nghĩ là tồn tại)?

Câu trả lời:


1045

Để phân định bằng một tab, bạn có thể sử dụng sepđối số to_csv:

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

Để sử dụng mã hóa cụ thể (ví dụ: 'utf-8'), hãy sử dụng encodingđối số:

df.to_csv(file_name, sep='\t', encoding='utf-8')

32
Tôi sẽ thêm index=Falseđể giảm chỉ số.
Medhat

11
Ban đầu tôi bối rối không biết làm thế nào tôi tìm được câu trả lời cho câu hỏi tôi đã viết 7 năm trước.
Hayden

250

Khi bạn đang lưu trữ một DataFrameđối tượng vào tệp csv bằng to_csvphương thức, có lẽ bạn sẽ không cần lưu trữ các chỉ số trước của mỗi hàng của DataFrameđối tượng.

Bạn có thể tránh điều đó bằng cách chuyển một Falsegiá trị boolean cho indextham số.

Hơi giống:

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

Vì vậy, nếu đối tượng DataFrame của bạn giống như:

  Color  Number
0   red     22
1  blue     10

Tệp csv sẽ lưu trữ:

Color,Number
red,22
blue,10

thay vì (trường hợp khi giá trị mặc định True được thông qua)

,Color,Number
0,red,22
1,blue,10

Điều gì nếu lập chỉ mục là mong muốn, nhưng cũng nên có một tiêu đề? Bạn chỉ sử dụng df.rename_axis('index_name')? điều đó không làm thay đổi chính tập tin
Zap

20

Để viết DataFrame của gấu trúc vào tệp CSV, bạn sẽ cần DataFrame.to_csv. Hàm này cung cấp nhiều đối số với mặc định hợp lý mà bạn sẽ thường xuyên hơn không cần ghi đè cho phù hợp với trường hợp sử dụng cụ thể của bạn. Ví dụ: bạn có thể muốn sử dụng một dấu phân cách khác, thay đổi định dạng ngày giờ hoặc bỏ chỉ mục khi viết. to_csvcó các đối số bạn có thể vượt qua để giải quyết các yêu cầu này.

Dưới đây là bảng liệt kê một số tình huống phổ biến khi ghi vào tệp CSV và các đối số tương ứng mà bạn có thể sử dụng cho chúng.

Viết thư cho CSV ma

Chú thích

  1. Dấu phân cách mặc định được giả sử là dấu phẩy ( ','). Đừng thay đổi điều này trừ khi bạn biết bạn cần.
  2. Theo mặc định, chỉ mục của dfđược viết là cột đầu tiên. Nếu DataFrame của bạn không có chỉ mục (IOW, df.indexlà mặc định RangeIndex), thì bạn sẽ muốn đặt index=Falsekhi viết. Để giải thích điều này theo một cách khác, nếu dữ liệu của bạn có một chỉ mục, bạn có thể (và nên) sử dụng index=Truehoặc chỉ để nó hoàn toàn (như mặc định là True).
  3. Sẽ là khôn ngoan khi đặt tham số này nếu bạn đang viết dữ liệu chuỗi để các ứng dụng khác biết cách đọc dữ liệu của bạn. Điều này cũng sẽ tránh bất kỳ tiềm năng nào UnicodeEncodeErrorbạn có thể gặp phải trong khi lưu.
  4. Nên nén nếu bạn đang ghi DataFrames lớn (> 100K hàng) vào đĩa vì nó sẽ dẫn đến các tệp đầu ra nhỏ hơn nhiều. OTOH, điều đó có nghĩa là thời gian ghi sẽ tăng lên (và do đó, thời gian đọc vì tệp sẽ cần được giải nén).

18

Một cái gì đó khác bạn có thể thử nếu bạn gặp vấn đề mã hóa thành 'utf-8' và muốn đi theo từng ô bạn có thể thử như sau.

Con trăn 2

(Trong đó "df" là đối tượng DataFrame của bạn.)

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

Vậy hãy thử đi:

df.to_csv(file_name)

Bạn có thể kiểm tra mã hóa của các cột bằng cách:

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

Cảnh báo: lỗi = 'bỏ qua' sẽ chỉ bỏ qua ký tự, ví dụ:

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

Con trăn 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

Đôi khi bạn phải đối mặt với những vấn đề này nếu bạn chỉ định mã hóa UTF-8. Tôi khuyên bạn nên chỉ định mã hóa trong khi đọc tệp và mã hóa tương tự trong khi ghi vào tệp. Điều này có thể giải quyết vấn đề của bạn.


7

Ví dụ về xuất trong tệp có đường dẫn đầy đủ trên Windows và trong trường hợp tệp của bạn có các tiêu đề :

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

Ví dụ nếu bạn muốn lưu trữ trong thư mục trong cùng thư mục chứa tập lệnh của bạn, với mã hóa utf-8tab làm dấu phân cách :

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

7

nó có thể không phải là câu trả lời cho trường hợp này, nhưng vì tôi có cùng thông báo lỗi với .to_csvtôi đã thử .toCSV('name.csv')và thông báo lỗi khác nhau (" SparseDataFrame' object has no attribute 'toCSV'). Vì vậy, vấn đề đã được giải quyết bằng cách chuyển dataframe thành dataframe dày đặc

df.to_dense().to_csv("submission.csv", index = False, sep=',', encoding='utf-8')

Bạn đã gặp lỗi trong lần thứ hai vì có vẻ như bạn đã sử dụng .toCSVvà không .to_csv. Bạn đã quên dấu gạch dưới
Kyle C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.