float64 dengan panda to_csv

93

Saya membaca CSV dengan angka float seperti ini:

Bob,0.085
Alice,0.005

Dan impor ke dalam bingkai data, dan tulis kerangka data ini ke tempat baru

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

Sekarang ini pandasfilememiliki:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Apa yang terjadi? mungkin saya harus melakukan cast ke tipe yang berbeda seperti float32 atau sesuatu?

Saya menggunakan pandas 0.9.0 dan numpy 1.6.2 .

avances123
sumber
28
Selamat datang di nomor floating point.
Ignacio Vazquez-Abrams
1
Duplikat stackoverflow.com/questions/1778368/…
Nathan Villaescusa
1
Saya membuat masalah untuk diperiksa lebih detail di sini: github.com/pydata/pandas/issues/2069 EDIT: Jika Anda bisa, harap taruh reproduksi mandiri dari masalah tersebut pada masalah GitHub. Saya tidak dapat mereproduksinya.
Wes McKinney

Jawaban:

168

Seperti disebutkan dalam komentar, ini adalah masalah floating point umum.

Namun Anda dapat menggunakan float_formatkata kunci to_csvuntuk menyembunyikannya:

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

atau, jika Anda tidak ingin 0,0001 dibulatkan menjadi nol:

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

akan memberimu:

Bob,0.085
Alice,0.005

di file keluaran Anda.

Untuk penjelasan tentang %g, lihat Spesifikasi Format Mini-Bahasa .

bmu
sumber
Saya mendapat kesalahanTypeError: __init__() got an unexpected keyword argument 'float_format'
95
Jika seseorang memiliki kesalahan yang sama dengan @ wander95, Anda mungkin perlu memperbarui pandaske versi yang lebih baru.
driftcatcher
10

PEMBARUAN: Jawaban akurat pada saat penulisan, dan presisi floating point masih bukan sesuatu yang Anda dapatkan secara default dengan to_csv / read_csv (pengorbanan kinerja presisi; default mendukung kinerja).

Saat ini ada yang float_formatargumen tersedia untukpandas.DataFrame.to_csv dan yang float_precisionargumen tersedia untukpandas.from_csv .

Dokumen asli masih layak dibaca untuk memahami masalahnya dengan lebih baik.


Itu adalah bug di panda, tidak hanya di fungsi "to_csv", tetapi juga di "read_csv". Ini bukan masalah floating point umum, meskipun benar bahwa aritmatika floating point adalah subjek yang membutuhkan perhatian dari programmer. Artikel di bawah ini menjelaskan sedikit tentang subjek ini:

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

Satu baris klasik yang menunjukkan "masalah" adalah ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... yang tidak menampilkan 0,3 seperti yang diharapkan. Di sisi lain, jika Anda menangani kalkulasi menggunakan aritmatika titik tetap dan hanya pada langkah terakhir Anda menggunakan aritmatika titik mengambang , perhitungan akan bekerja seperti yang Anda harapkan. Lihat ini:

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

Jika Anda sangat ingin mengatasi masalah ini, saya sarankan Anda membuat file CSV lain yang berisi semua angka sebagai bilangan bulat, misalnya mengalikan dengan 100, 1000 atau faktor lain yang ternyata nyaman. Di dalam aplikasi Anda, baca file CSV seperti biasa dan Anda akan mendapatkan kembali angka integer tersebut. Kemudian ubah nilai tersebut menjadi floating point, bagi dengan faktor yang sama yang Anda kalikan sebelumnya.

Richard Gomes
sumber