不一致的pandas read_csv dtype推断大型TSV文件中的大部分整数字符串列

时间:2013-08-27 17:25:29

标签: python pandas csv types type-inference

我有一个制表符分隔文件,其中一列应该被解释为字符串,但许多条目都是整数。使用小文件read_csv在看到一些非整数值后正确地将列解释为字符串,但是对于较大的文件,这不起作用:

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 阅读和写作并不能解决问题。理想情况下,我可以通过引用我的字符串数据来解决这个问题,并以某种方式迫使pandas不对引用的数据进行任何推断。

使用pandas 0.12.0

2 个答案:

答案 0 :(得分:6)

为避免让Pandas推断出您的数据类型,请为read_csv提供converters参数:

  

converters:dict。可选的

     

用于转换某些列中的值的函数的字典。键可以是整数或列标签

对于您的文件,这将是:

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

我对文档的阅读是您不需要为每列指定转换器。 Pandas应继续推断未指定列的数据类型。

答案 1 :(得分: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)

注意:如果您正在寻找存储DataFrames的解决方案,例如在会话之间,pickle和HDF5Store都是优秀的解决方案,不受这些类型的解析错误的影响(并且会快得多)。 请参阅:How to store data frame using PANDAS, Python