2013-06-04 74 views
6

所以我在讀從NOAA站碼CSV文件看起來像這樣:熊貓read_csv D型前導零

"USAF","WBAN","STATION NAME","CTRY","FIPS","STATE","CALL","LAT","LON","ELEV(.1M)","BEGIN","END" 
"006852","99999","SENT","SW","SZ","","","+46817","+010350","+14200","","" 
"007005","99999","CWOS 07005","","","","","-99999","-999999","-99999","20120127","20120127" 

前兩列包含氣象站代碼,有時還前導零。當熊貓在沒有指定dtype的情況下導入它們時,它們會變成整數。這並不是什麼大事,因爲我可以循環訪問數據框索引並用"%06d" % i之類的東西代替它們,因爲它們總是六位數字,但是您知道......這是懶惰的方式。

使用此代碼得到的CSV:

file = urllib.urlopen(r"ftp://ftp.ncdc.noaa.gov/pub/data/inventories/ISH-HISTORY.CSV") 
output = open('Station Codes.csv','wb') 
output.write(file.read()) 
output.close() 

這是一個好主意,但是當我去嘗試,並使用該閱讀:

import pandas as pd 
df = pd.io.parsers.read_csv("Station Codes.csv",dtype={'USAF': np.str, 'WBAN': np.str}) 

import pandas as pd 
df = pd.io.parsers.read_csv("Station Codes.csv",dtype={'USAF': str, 'WBAN': str}) 

我收到一條令人討厭的錯誤消息:

File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 401, in parser 
_f 
    return _read(filepath_or_buffer, kwds) 
    File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 216, in _read 
    return parser.read() 
    File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 633, in read 
    ret = self._engine.read(nrows) 
    File "C:\Python27\lib\site-packages\pandas-0.11.0-py2.7-win32.egg\pandas\io\parsers.py", line 957, in read 
    data = self._reader.read(nrows) 
    File "parser.pyx", line 654, in pandas._parser.TextReader.read (pandas\src\parser.c:5931) 
    File "parser.pyx", line 676, in pandas._parser.TextReader._read_low_memory (pandas\src\parser.c:6148) 
    File "parser.pyx", line 752, in pandas._parser.TextReader._read_rows (pandas\src\parser.c:6962) 
    File "parser.pyx", line 837, in pandas._parser.TextReader._convert_column_data (pandas\src\parser.c:7898) 
    File "parser.pyx", line 887, in pandas._parser.TextReader._convert_tokens (pandas\src\parser.c:8483) 
    File "parser.pyx", line 953, in pandas._parser.TextReader._convert_with_dtype (pandas\src\parser.c:9535) 
    File "parser.pyx", line 1283, in pandas._parser._to_fw_string (pandas\src\parser.c:14616) 
TypeError: data type not understood 

這是一個非常大的csv(31k行),所以也許這與它有什麼關係?

+0

我發現,使用對象的工作,以保持前導零:D型= {'USAF':object,'WBAN':object} from this post:http:// stackoverflow。com/questions/13293810/import-pandas-dataframe-column-as-string-not-int –

+0

有點奇怪,str/np.str不能正常工作......:SI不知道它是否是一個bug,可能值得發佈[github上的問題](https://github.com/pydata/pandas/issues)。 –

+0

是的,我認爲這很奇怪,因爲我可以在那裏使用其他數字數據類型。 –

回答

2

它看起來像你必須指定字符串的長度,如果你不希望它是一個對象。
例如:

dtype={'USAF': '|S6'} 

我找不到此參考,但我似乎記得韋斯(也許在談話)討論這個非常問題。他建議numpy不允許使用「適當的」可變長度的字符串(請參閱此question/answer),並且使用最大長度來填充數組通常會比空間效率低得多(即使字符串很短,它將用作許多空間作爲最長的字符串)。

由於@Wes所指出的,這也是一種情況:

dtype={'USAF': object} 

作品一樣好。

+2

我會建議只是'{'USAF':object}' –

+1

@WesMcKinney優點(一如既往)! –

5

這個問題導致我用序列號解析文件時頭疼。由於未知原因,00794和000794是兩個不同的序列號。我終於想出了

converters={'serial_number': lambda x: str(x)} 
+1

爲什麼不寫'轉換器= {'serial_number':str}'? –

+0

可能是因爲我沒有想到:) –

+0

不適用於熊貓== 0.20.2 –

4

這是大熊貓的問題DTYPE猜測

熊貓看到的數字和猜測你想它是數字。

爲了使大熊貓不懷疑你的意圖,你應該設置你想要的D型:object

pd.read_csv('filename.csv', dtype={'leading_zero_column_name': object}) 

會做的伎倆

+0

有關更多信息,'read_csv'方法返回一個[DataFrame。](http://pandas.pydata.org/ pandas-docs/stable/generated/pandas.DataFrame.html#pandas.DataFrame)並且推斷每個字段的默認值。通過明確聲明'dtype',生成的DataFrame將正確處理字段。 – Nathan

+0

不適用於熊貓== 0.20.2 –

+0

@DanielM你確定嗎? Doc對於0.22聲明它應該。我已經在0.11 - > 0.14中測試過了,所以在以下版本中沒有這種行爲會很奇怪... – firelynx