float64 ile pandalar to_csv


93

Bunun gibi kayan sayılara sahip bir CSV okuyorum:

Bob,0.085
Alice,0.005

Ve bir veri çerçevesine aktarın ve bu veri çerçevesini yeni bir yere yazın

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

Şimdi bu pandasfilevar:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Ne oluyor? belki float32 veya başka bir şey gibi farklı bir türe çevirmem gerekiyor?

Im kullanarak pandalar 0.9.0 ve 1.6.2 numpy .


28
Kayan noktalı sayılara hoş geldiniz.
Ignacio Vazquez-Abrams


1
Burada biraz daha ayrıntılı olarak incelemek için bir sorun oluşturdum: github.com/pydata/pandas/issues/2069 DÜZENLE: Yapabiliyorsanız, lütfen GitHub sorununa sorunun bağımsız bir kopyasını ekleyin . Onu yeniden üretemiyorum.
Wes McKinney

Yanıtlar:


168

Yorumlarda belirtildiği gibi, genel bir kayan nokta problemidir.

Ancak gizlemek için float_formatanahtar kelimesini kullanabilirsiniz to_csv:

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

veya 0.0001'in sıfıra yuvarlanmasını istemiyorsanız:

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

sana vereceğim:

Bob,0.085
Alice,0.005

çıktı dosyanızda.

Bunun açıklaması için %g, bkz. Biçim Belirtimi Mini Dil .


Bir hata aldımTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95

Birisi @ wander95 ile aynı hatayı alıyorsa, muhtemelen pandasdaha yeni bir sürüme güncellemeniz gerekir .
driftcatcher

10

GÜNCELLEME: Yazma sırasında yanıt doğruydu ve kayan nokta hassasiyeti hala varsayılan olarak to_csv / read_csv ile elde ettiğiniz bir şey değildir (kesinlik-performans değiş tokuşu; varsayılanlar performans lehinedir).

Günümüzde var hazır argüman ve mevcut argümanfloat_formatpandas.DataFrame.to_csvfloat_precisionpandas.from_csv .

Sorunu daha iyi anlamak için orijinali okumaya değer.


Pandalarda, sadece "to_csv" işlevinde değil, "read_csv" de de bir hataydı. Kayan nokta aritmetiğinin , programcıdan biraz özen isteyen bir konu olduğu doğru olmasına rağmen, bu genel bir kayan nokta sorunu değildir . Aşağıdaki bu makale bu konuyu biraz aydınlatmaktadır:

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

"Sorunu" gösteren klasik bir tek satırlık çizgi ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... beklendiği gibi 0,3 göstermeyen. Öte yandan, hesaplamayı sabit nokta aritmetiği kullanarak gerçekleştirirseniz ve yalnızca son adımda kayan nokta aritmetiğini kullanırsanız , beklediğiniz gibi çalışacaktır. Bunu gör:

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

Eğer bu sorunu umutsuzca aşmanız gerekiyorsa, tüm rakamları tamsayı olarak içeren başka bir CSV dosyası oluşturmanızı tavsiye ederim, örneğin 100, 1000 ile çarpma veya uygun olan başka bir faktör. Başvurunuzun içinde, CSV dosyasını her zamanki gibi okuyun ve bu tam sayı rakamlarını geri alacaksınız. Daha sonra bu değerleri, daha önce çarptığınız çarpana bölerek kayan noktaya dönüştürün.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.