Inconsistent pandas read_csv dtype inference on mostly-integer string column in huge TSV file
我有一个制表符分隔文件,其中一列应该被解释为一个字符串,但许多条目都是整数。 使用小文件read_csv在看到一些非整数值后正确地将列解释为字符串,但是对于较大的文件,这不起作用:
1 2 3 4 5 6 7 | 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 2 3 4 5 6 7 8 9 10 11 | ['1' 'X' 1] '1' '1' '1' '1' 1 1 1 1 1 1 |
有趣的是262144是2的幂,所以我认为推理和转换发生在块中,但是正在跳过一些块。
我相当肯定这是一个错误,但是想要一个可能使用引用的解决方法,尽管这样做
引用= csv.QUOTE_NONNUMERIC
阅读和写作并不能解决问题。 理想情况下,我可以通过引用我的字符串数据来解决这个问题,并以某种方式迫使pandas不对引用的数据进行任何推断。
使用pandas 0.12.0
为避免让Pandas推断出您的数据类型,请为
converters : dict. optionalDict of functions for converting values in certain columns. Keys can either be integers or column labels
对于您的文件,这将看起来像:
1 | df2 = pd.read_csv('test', sep='\t', converters={'a':str}) |
我对文档的阅读是,您不需要为每列指定转换器。 Pandas应继续推断未指定列的数据类型。
你在这里欺骗了read_csv解析器(公平地说,我不认为无论你扔什么都不能正常输出)......但是,它可能是一个错误!
正如@Steven指出你可以使用read_csv的converter参数:
1 | df2 = pd.read_csv('test', sep='\t', converters={'a': str}) |
一个懒惰的解决方案就是在你读完文件后修补它:
1 2 3 4 | In [11]: df2['a'] = df2['a'].astype('str') # now they are equal In [12]: pd.util.testing.assert_frame_equal(df, df2) |
注意:如果您正在寻找存储DataFrame的解决方案,例如 在会话之间,pickle和HDF5Store都是优秀的解决方案,不受这些类型的解析错误的影响(并且会快得多)。 请参阅:如何使用PANDAS,Python存储数据框