2014-06-23 73 views
0

我想將excel(xlsx)文件中的數據轉儲到使用xlrd模塊的文本文件中,並遇到浮動進動的問題。Python Xlrd浮動進動問題

找到了一些類似問題的帖子,其中歲差丟失了16位十進制數字中的最後一位。

下面是XLSX複製的數據:

VALUE;DATA 
1.01 HELLO 
2.11 1/1/2014 
3.21 ONE 
4.31 1/1/2014 12:14 
5.441 $10 
6.241 TWO 
77.11 Zulfi 
8.11 99 
9.11 99.999 
10.11 0 

下面是我從xlrd得到:

1.01|'HELLO' 
2.1099999999999999|'2014-01-01 00:00:00.000000' 
3.21|'ONE' 
4.3099999999999996|'2014-01-01 12:14:00.000000' 
5.4409999999999998|10.0 
6.2409999999999997|'TWO' 
77.109999999999999|'Zulfi' 
8.1099999999999994|99.0 
9.1099999999999994|99.998999999999995 
10.109999999999999|0.0 
  1. 「2.11」 已經成爲 「2.1099999999999999」 和 「4.31」 已經成爲「4.3099999999999996」等...
  2. 「$ 10」已成爲「10」
  3. 日期值看起來有點不同(此一個我瞭解和我得到了我的編碼)

我明白花車的一些奧祕那裏有鬆動歲差對於具有太多的數字發佈十進制值的可能性,但在這裏我只有兩個數字。

我通過與開源ETL工具「Pentaho」(用java編寫)進行比較來測試輸出,該工具可以讀取/寫入excel文件,並且該工具看起來沒有問題,因爲它們出現在xlsx文件中(田野裏讀爲字符串和數字,長度30和旋進20)

這裏是Pentaho的讀取

VALUE;DATA 
1.01;HELLO 
2.11;2014/01/01 00:00:00.000 
3.21;ONE 
4.31;2014/01/01 12:14:00.000 
5.441; 10.0 
6.241;TWO 
77.11;Zulfi 
8.11; 99.0 
9.11; 99.999 
10.11; 0.0 

以下是我的Python代碼:

for rownum in xrange(sh.nrows): 
    for colnum in xrange(sh.ncols): 
     cell_obj = sh.cell(rownum,colnum) 
     cell_val=sh.cell_value(rownum,colnum) 
     if cell_obj.ctype == xlrd.XL_CELL_DATE: 
      year, month, day, hour, minute, second = xlrd.xldate_as_tuple(cell_val, wb.datemode) 
      py_date = datetime.datetime(year, month, day, hour, minute, second).strftime("%Y-%m-%d %H:%M:%S.%f") 
      cell_val = py_date 
     if (colnum==0): 
      row_values=repr(cell_val) 
     else : 
      row_values=row_values+fdel+repr(cell_val) 
    if (((row_values).find("\\n"))>-1): 
     NLFlag=1 
    file_output.write((row_values).replace('\\n','') + "\n") 
    row_values='' 
file_output.close() 

對此的任何幫助都非常感謝。

感謝

+0

嘗試將您的Excel文件另存爲.xls。 python excel模塊是爲這種格式編寫的,所以這可能是一個促成因素。除此之外,你可能只需要處理電腦無法處理浮動的事實。 – wnnmaw

+0

@wnnmaw:我會說電腦處理浮動很好。主要是遇到麻煩的人。 :-) –

+0

[浮點限制]的可能重複(http://stackoverflow.com/questions/406361/floating-point-limitations) –

回答

0

花車,又名雙精度實數,只有精度約16個十進制數字。當分數的形式爲2^-n時,它們只能表示小數部分,因此可以是1/8或1/1024的倍數。所有其他小數可能不準確。

如果您打印出沒有進一步說明的浮點數,您將得到系統盡最大努力以十進制表示二進制分數,因此2.099999999999等而不是2.1。但是,如果你知道你的花車並不代表比(比如說)3張十進制數越多,那麼你可以強制它們用

file_output.write('{0:.3f}'.format(f_num)) 

將輸出f_num正確使用字符串格式功能輸出圓潤,例如向下舍入並用零填充到3個位置

我想,默認情況下,xlrd庫將解釋任何可以作爲浮點的字段。應該有一個開關強制所有的讀取爲字符串,在這種情況下,您打印的內容將與您閱讀的內容完全相同。

+0

'xlrd'庫在這裏沒有做任何解釋:Excel文件包含一個(二進制)浮點數,'xlrd'完全讀取二進制浮點數。令人困惑的是,Excel和Python(順便說一句,看起來像Python 2.6)選擇以不同的方式顯示該浮點數:Excel隱藏了不精確性,而Python顯示了其中的一部分。 –

+0

所以基本上Python打印出16位精度,而Excel工作到15,然後忽略尾部0,並打印剩下的部分。這可以說是這種情況下用戶更友好的事情。就像您在電子表格中輸入數字一樣,它們將會有少量數字。如果您擔心15位和16位數字之間的差異,那麼您是一位更復雜的用戶,並且會讓您瞭解如何獲取這些數字。 –

+0

是的,非常多(儘管Python的輸出基於17位有效數字,而不是16位)。關鍵是Excel和Python都存儲完全相同的數值;他們只在選擇顯示價值方面有所不同。 (關於這兩種顯示方法的相對優點,有一些爭論,但我不確定這是否適合他們。) –