2013-08-27 77 views
6

我有一個選項卡分隔的文件應該被解釋爲一個字符串的列,但許多條目是整數。小文件read_csv正確解釋該列作爲字符串看到一些非整數值之後,但較大的文件,這不工作:熊貓read_csv dtype推斷問題

import pandas as pd 
df = pd.DataFrame({'a':['1']*100000 + ['X']*100000 + ['1']*100000, 'b':['b']*300000}) 
df.to_csv('test', sep='\t', index=False, na_rep='NA') 
df2 = pd.read_csv('test', sep='\t') 
print df2['a'].unique() 
for a in df2['a'][262140:262150]: 
    print repr(a) 

輸出:

['1' 'X' 1] 
'1' 
'1' 
'1' 
'1' 
1 
1 
1 
1 
1 
1 

有趣262144是2的冪所以我認爲推理和轉換正在發生,但跳過了一些塊。

我相當肯定這是一個錯誤,但想周圍的工作,也許用報價,雖然加入 報價= csv.QUOTE_NONNUMERIC 閱讀和寫作不解決問題。理想情況下,我可以通過引用字符串數據來解決此問題,並以某種方式強制大熊貓不對引用數據進行任何推理。

使用熊貓0.12.0

+2

[docs](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html)使它看起來像這樣會工作:'pd.read_csv(' test',sep ='\ t',轉換器= {'a':str})''。 –

+0

@StevenRumbalski它完全沒有!你應該添加這個答案! –

+0

@AndyHayden:謝謝 - 已完成。 –

回答

5

你在這裏受騙的read_csv解析器(和是公平的,我不認爲它可以總是預期正確輸出不管你扔什麼的吧) ...但是,它可能是a bug

由於@Steven指出可以使用的read_csv轉換器參數:

df2 = pd.read_csv('test', sep='\t', converters={'a': str}) 

懶惰的解決辦法就是修補這個了,你在文件中讀過之後:

In [11]: df2['a'] = df2['a'].astype('str') 

# now they are equal 
In [12]: pd.util.testing.assert_frame_equal(df, df2) 

注:如果您正在尋找存儲數據幀的解決方案,例如在會話之間,pickle和HDF5Store都是優秀的解決方案,不會受到這些類型的解析錯誤的影響(並且速度會更快)。 見:How to store data frame using PANDAS, Python

+0

這是我的後備,但每次讀取我試圖避免的文件時都會出現額外的代碼行 – andrew

+0

解決方案可能不會使用to_csv/read_csv來存儲您DataFrames,to_pickle或hdf5_store是更好的解決方案(並且都不會受這種解析錯誤影響)。 –

+0

@ user1068490更新了關於該鏈接的另一個答案 –

6

爲了避免大熊貓推斷你的數據類型,提供了一個converters參數read_csv

converters:字典。可選

用於轉換某些列中的值的函數的字典。鍵可以是整數或列標籤

爲您的文件,這將是這樣的:

df2 = pd.read_csv('test', sep='\t', converters={'a':str}) 

我的文檔的解讀是,你並不需要爲每列指定轉換器。大熊貓應該繼續推斷未指定列的數據類型。