การเขียน DataFrame นุ่นเป็นไฟล์ CSV


714

ฉันมี dataframe เป็นหมีแพนด้าซึ่งฉันต้องการจะเขียนไปยังไฟล์ CSV ฉันกำลังทำสิ่งนี้โดยใช้:

df.to_csv('out.csv')

และได้รับข้อผิดพลาด:

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

มีวิธีใดบ้างที่จะหลีกเลี่ยงสิ่งนี้ได้อย่างง่ายดาย (เช่นฉันมีอักขระ Unicode ในกรอบข้อมูลของฉัน)? และมีวิธีการเขียนไปยังไฟล์ที่คั่นด้วยแท็บแทนการใช้ CSV เช่นวิธีการ 'to-tab' (ที่ฉันไม่คิดว่ามีอยู่)?

คำตอบ:


1045

หากต้องการกำหนดเขตโดยแท็บคุณสามารถใช้sepอาร์กิวเมนต์ของto_csv:

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

หากต้องการใช้การเข้ารหัสเฉพาะ (เช่น 'utf-8') ให้ใช้encodingอาร์กิวเมนต์:

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

32
ฉันจะเพิ่มindex=Falseเพื่อวางดัชนี
Medhat

11
ตอนแรกฉันสับสนว่าฉันพบคำตอบของคำถามที่ฉันเขียนไปแล้วเมื่อ 7 ปีที่แล้ว
เฮย์เดน

250

เมื่อคุณจัดเก็บDataFrameวัตถุลงในไฟล์ csvโดยใช้to_csvวิธีการคุณอาจไม่จำเป็นต้องจัดเก็บดัชนีก่อนหน้าของแต่ละแถวของDataFrameวัตถุ

คุณสามารถหลีกเลี่ยงได้โดยส่งFalseค่าบูลีนไปยังindexพารามิเตอร์

ค่อนข้างชอบ:

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

ดังนั้นหากออบเจ็กต์ DataFrame ของคุณมีลักษณะดังนี้:

  Color  Number
0   red     22
1  blue     10

ไฟล์ csv จะจัดเก็บ:

Color,Number
red,22
blue,10

แทน (กรณีที่เมื่อค่าเริ่มต้น Trueถูกส่งผ่าน)

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

จะทำอย่างไรถ้าต้องการจัดทำดัชนี แต่ควรมีชื่อด้วย? คุณเพิ่งใช้df.rename_axis('index_name')ไหม ที่ไม่ได้ปรับเปลี่ยนไฟล์ตัวเอง
แซบ

19

การเขียน DataFrame หมีแพนด้าเพื่อไฟล์ CSV DataFrame.to_csvคุณจะต้อง ฟังก์ชั่นนี้มีข้อโต้แย้งมากมายพร้อมค่าเริ่มต้นที่สมเหตุสมผลซึ่งคุณมักจะไม่จำเป็นต้องแทนที่เพื่อให้เหมาะกับกรณีการใช้งานเฉพาะของคุณ ตัวอย่างเช่นคุณอาจต้องการใช้ตัวคั่นอื่นเปลี่ยนรูปแบบวันที่และเวลาหรือเขียนดัชนีเมื่อเขียน to_csvมีข้อโต้แย้งที่คุณสามารถส่งผ่านไปยังที่อยู่ข้อกำหนดเหล่านี้

ต่อไปนี้เป็นตารางที่แสดงรายการสถานการณ์ทั่วไปของการเขียนไฟล์ CSV และอาร์กิวเมนต์ที่เกี่ยวข้องที่คุณสามารถใช้ได้

เขียนถึง CSV เพื่อน

เชิงอรรถ

  1. ตัวคั่นเริ่มต้นจะถือว่าเป็นเครื่องหมายจุลภาค ( ',') อย่าเปลี่ยนสิ่งนี้จนกว่าคุณจะรู้ว่าคุณต้องการ
  2. โดยค่าเริ่มต้นดัชนีของdfจะถูกเขียนเป็นคอลัมน์แรก หาก DataFrame ของคุณไม่มีดัชนี (IOW df.indexนั่นคือค่าเริ่มต้นRangeIndex) คุณจะต้องตั้งค่าindex=Falseเมื่อเขียน เพื่ออธิบายสิ่งนี้ในวิธีที่แตกต่างกันหากข้อมูลของคุณมีดัชนีคุณสามารถ (และควร) ใช้index=Trueหรือเพียงแค่ปล่อยให้มันสมบูรณ์ (ตามค่าเริ่มต้นคือTrue)
  3. คุณควรตั้งค่าพารามิเตอร์นี้หากคุณกำลังเขียนข้อมูลสตริงเพื่อให้แอปพลิเคชันอื่นรู้วิธีอ่านข้อมูลของคุณ สิ่งนี้จะหลีกเลี่ยงสิ่งที่อาจUnicodeEncodeErrorเป็นไปได้ที่คุณอาจพบในขณะบันทึก
  4. ขอแนะนำให้ใช้การบีบอัดถ้าคุณกำลังเขียน DataFrames ขนาดใหญ่ (> 100K แถว) ลงดิสก์เนื่องจากจะทำให้ไฟล์เอาต์พุตมีขนาดเล็กลงมาก OTOH หมายถึงเวลาในการเขียนจะเพิ่มขึ้น (และดังนั้นเวลาอ่านเนื่องจากไฟล์จะต้องถูกคลายการบีบอัด)

18

อย่างอื่นที่คุณสามารถลองได้หากคุณมีปัญหาในการเข้ารหัสเป็น 'utf-8' และต้องการไปที่เซลล์โดยเซลล์คุณสามารถลองต่อไปนี้

Python 2

(โดยที่ "df" เป็นวัตถุ 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

จากนั้นลอง:

df.to_csv(file_name)

คุณสามารถตรวจสอบการเข้ารหัสคอลัมน์ได้โดย:

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

คำเตือน: ข้อผิดพลาด = 'ละเว้น' จะไม่แสดงตัวอักษรเช่น

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

บางครั้งคุณประสบปัญหาเหล่านี้หากคุณระบุการเข้ารหัส UTF-8 ด้วย ฉันขอแนะนำให้คุณระบุการเข้ารหัสในขณะที่อ่านไฟล์และการเข้ารหัสเดียวกันในขณะที่เขียนไปยังไฟล์ วิธีนี้อาจช่วยแก้ปัญหาของคุณได้


7

ตัวอย่างของการส่งออกเป็นไฟล์ที่มีเส้นทางแบบเต็มบน Windowsและในกรณีที่ไฟล์ของคุณมีส่วนหัว :

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

ตัวอย่างถ้าคุณต้องการเก็บไว้ในโฟลเดอร์ในไดเรกทอรีเดียวกับที่สคริปต์ของคุณพร้อมด้วยการเข้ารหัส utf-8และแท็บเป็นตัวคั่น :

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

7

อาจไม่ใช่คำตอบสำหรับกรณีนี้ แต่เนื่องจากฉันมีข้อความแสดงข้อผิดพลาดเดียวกันกับที่.to_csvฉันลอง.toCSV('name.csv')และข้อความแสดงข้อผิดพลาดแตกต่างกัน (" SparseDataFrame' object has no attribute 'toCSV') ดังนั้นปัญหาจึงได้รับการแก้ไขโดยเปลี่ยน dataframe เป็น dataframe หนาแน่น

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

คุณได้รับข้อผิดพลาดในหนึ่งวินาทีในขณะที่มันดูเหมือนว่าคุณใช้และไม่ได้.toCSV .to_csvคุณลืมขีดล่าง
Kyle C
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.