2013-06-04 122 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