2016-09-14 50 views
0

我知道使用==來浮動一般是不安全的。但它是否適用於以下情況?Python如何爲float/double工作?

  1. 從csv文件中讀取A.csv,將前半部分的數據保存到csv文件B.csv中,而不做任何事情。
  2. 從A.csv和B.csv中讀取。使用==來檢查數據是否在上半年到處匹配。

這些都是用大熊貓完成的。 A.csv中的列具有datetime,string和float類型。顯然==適用於日期時間和字符串,所以如果==也適用於float,在這種情況下,它可以節省很多工作。

它似乎在爲我所有的測試工作,但我可以認爲它會一直工作嗎?

+1

==對於任何類型的數字都是完全安全的。他們是平等的,或者他們不是。問題來自於你比較具有不同表示的數字。例如''2.3'== 2.3'可能無法正常工作,儘管它們在視覺上完全相同 –

+0

哦,沒有注意到熊貓的部分 –

+0

請參閱http://stackoverflow.com/q/26091689/2800918 – CAB

回答

3

當通過相同的分析例程時,相同的字符串表示形式將成爲相同的浮點表示形式。當對數值執行數學運算或者使用高精度表示時,浮點不準確性問題會發生,但是在低精度值上的相等性是沒有理由擔心的。

3

不,你不能認爲這會一直工作。

爲了達到這個目的,您需要知道熊貓在寫入CSV文件時寫出的文本值在讀回時(再次使用熊貓)會恢復完全相同的值。但默認情況下,Pandas函數會犧牲速度的準確性,所以解析操作而不是會自動恢復相同的浮點數。

爲了演示這一點,請嘗試以下操作:我們將創建一些隨機值,將它們寫入CSV文件並重新讀入,全部使用Pandas。首先,有必要進口:

>>> import pandas as pd 
>>> import numpy as np 

現在創建一些隨機值,並把它們變成一個熊貓Series對象:

>>> test_values = np.random.rand(10000) 
>>> s = pd.Series(test_values, name='test_values') 

現在我們用to_csv方法寫入這些值到一個文件,並然後閱讀文件的內容返回到一個DataFrame

>>> s.to_csv('test.csv', header=True) 
>>> df = pd.read_csv('test.csv') 

最後,讓我們從相關提取值列df並進行比較。我們將對==操作的結果進行求和,以確定有多少個10000輸入值被準確恢復。

>>> sum(test_values == df['test_values']) 
7808 

所以大約78%的數值被正確地恢復了;其他人不是。

此行爲被認爲是熊貓的一項功能,而不是一個錯誤。但是,有一個解決方法:Pandas 0.15爲CSV閱讀器添加了一個新的參數float_precision。通過將float_precision='round_trip'提供給read_csv操作,Pandas使用更慢但更準確的解析器。試着對上面的例子,我們得到的值完美恢復:

>>> df = pd.read_csv('test.csv', float_precision='round_trip') 
>>> sum(test_values == df['test_values']) 
10000 

這是第二個例子,在另一個方向。前面的例子表明寫入然後讀取不會返回相同的數據。這個例子表明閱讀然後寫作也不保存數據。該設置與您在問題中描述的設置緊密匹配。首先,我們將使用規則間隔值,而不是隨機的人創造A.csv,此時:

>>> import pandas as pd, numpy as np 
>>> s = pd.Series(np.arange(10**4)/1e3, name='test_values') 
>>> s.to_csv('A.csv', header=True) 

現在我們讀到A.csv,並背出再次寫入數據的上半年B.csv,在你的第1步。

>>> recovered_s = pd.read_csv('A.csv').test_values 
>>> recovered_s[:5000].to_csv('B.csv', header=True) 

然後,我們在這兩個A.csvB.csv閱讀,和A上半年B比較,因爲在你的第2步

>>> a = pd.read_csv('A.csv').test_values 
>>> b = pd.read_csv('B.csv').test_values 
>>> (a[:5000] == b).all() 
False 
>>> (a[:5000] == b).sum() 
4251 

再次,幾個值不能正確比較。打開文件,A.csv看起來非常符合我的預期。這裏是前15項中A.csv

,test_values 
0,0.0 
1,0.001 
2,0.002 
3,0.003 
4,0.004 
5,0.005 
6,0.006 
7,0.007 
8,0.008 
9,0.009 
10,0.01 
11,0.011 
12,0.012 
13,0.013 
14,0.014 
15,0.015 

這裏有相應的條目B.csv

,test_values 
0,0.0 
1,0.001 
2,0.002 
3,0.003 
4,0.004 
5,0.005 
6,0.006 
7,0.006999999999999999 
8,0.008 
9,0.009000000000000001 
10,0.01 
11,0.011000000000000001 
12,0.012 
13,0.013000000000000001 
14,0.013999999999999999 
15,0.015 

對引進float_precision關鍵字來read_csv更多信息,請參閱本bug report