float64 กับแพนด้า to_csv


93

ฉันกำลังอ่าน CSV ที่มีตัวเลขลอยดังนี้:

Bob,0.085
Alice,0.005

และนำเข้าสู่ dataframe และเขียน dataframe นี้ไปยังตำแหน่งใหม่

df = pd.read_csv(orig)
df.to_csv(pandasfile)

ตอนนี้pandasfileมี:

Bob,0.085000000000000006
Alice,0.0050000000000000001

เกิดอะไรขึ้น? บางทีฉันอาจต้องแคสต์เป็นประเภทอื่นเช่น float32 หรืออะไร?

Im ใช้หมีแพนด้า 0.9.0และ1.6.2 numpy


28
ยินดีต้อนรับสู่ตัวเลขทศนิยม
Ignacio Vazquez-Abrams


1
ฉันสร้างปัญหาเพื่อตรวจสอบรายละเอียดเพิ่มเติมที่นี่: github.com/pydata/pandas/issues/2069แก้ไข: หากทำได้โปรดใส่ปัญหาที่เกิดขึ้นใหม่แบบสแตนด์อโลนในปัญหา GitHub ฉันไม่สามารถทำซ้ำได้
Wes McKinney

คำตอบ:


168

ตามที่กล่าวไว้ในความคิดเห็นเป็นปัญหาจุดลอยตัวทั่วไป

อย่างไรก็ตามคุณสามารถใช้float_formatคำสำคัญto_csvเพื่อซ่อน:

df.to_csv('pandasfile.csv', float_format='%.3f')

หรือถ้าคุณไม่ต้องการให้ 0.0001 ถูกปัดเศษเป็นศูนย์:

df.to_csv('pandasfile.csv', float_format='%g')

จะให้คุณ:

Bob,0.085
Alice,0.005

ในไฟล์ผลลัพธ์ของคุณ

สำหรับคำอธิบายของ%gดูรูปแบบจำเพาะ Mini-ภาษา


ฉันได้รับข้อผิดพลาดTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95

หากมีใครพบข้อผิดพลาดเหมือนกับ @ wander95 คุณอาจต้องอัปเดตpandasเป็นเวอร์ชันที่ใหม่กว่า
driftcatcher

10

อัปเดต:คำตอบนั้นถูกต้องในขณะที่เขียนและความแม่นยำของจุดลอยตัวยังไม่ใช่สิ่งที่คุณจะได้รับโดยค่าเริ่มต้นด้วย to_csv / read_csv (การแลกเปลี่ยนประสิทธิภาพความแม่นยำค่าเริ่มต้นเป็นค่าเริ่มต้นสำหรับประสิทธิภาพ)

ปัจจุบันมีอาร์กิวเมนต์ใช้ได้สำหรับการและอาร์กิวเมนต์ใช้ได้สำหรับfloat_formatpandas.DataFrame.to_csvfloat_precisionpandas.from_csv

ต้นฉบับยังคงควรค่าแก่การอ่านเพื่อให้เข้าใจปัญหาได้ดีขึ้น


มันเป็นข้อบกพร่องในแพนด้าไม่เพียง แต่ในฟังก์ชัน "to_csv" เท่านั้น แต่ใน "read_csv" ด้วย ไม่ใช่ปัญหาเรื่องทศนิยมทั่วไปแม้ว่าจะเป็นเรื่องจริงที่ว่าเลขคณิตลอยตัวเป็นเรื่องที่ต้องการการดูแลจากโปรแกรมเมอร์ บทความด้านล่างนี้ชี้แจงเรื่องนี้เล็กน้อย:

http://docs.python.org/2/tutorial/floatingpoint.html

หนึ่งซับคลาสสิกที่แสดง "ปัญหา" คือ ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

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

>>> (1 + 1 + 1)  * 1.0 / 10
0.3

หากคุณต้องการหลีกเลี่ยงปัญหานี้อย่างยิ่งเราขอแนะนำให้คุณสร้างไฟล์ CSV อื่นซึ่งมีตัวเลขทั้งหมดเป็นจำนวนเต็มตัวอย่างเช่นการคูณด้วย 100, 1000 หรือปัจจัยอื่น ๆ ซึ่งจะทำให้สะดวก ภายในแอปพลิเคชันของคุณให้อ่านไฟล์ CSV ตามปกติและคุณจะได้รับตัวเลขจำนวนเต็มกลับคืนมา จากนั้นแปลงค่าเหล่านั้นเป็นทศนิยมหารด้วยปัจจัยเดียวกับที่คุณคูณก่อนหน้านี้

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