pd.read_csv的截断问题

时间:2014-05-08 06:52:39

标签: python csv pandas

我想就pandas.read_csv例程中注意到的问题寻求补救步骤的指导。当我使用pd.to_csv将长整数存储到文件中时,它可以很好地存储数据 - 但是当我使用pd.read_csv将其读回时,它会与最后3位数混淆。当我尝试使用to_csv(没有任何编辑)再次将其保存回来时,生成的CSV文件中的数字与原始CSV文件不同。我已经说明了下面的问题(请注意4321113141090630389如何变为4321113141090630400并且4321583677327450765变为4321583677327450880):

由pd.to_csv创建的原始CSV文件:

grep -e 321583677327450 -e 321113141090630 orig.piece 
orig.piece:1,1;0;0;0;1;1;3844;3844;3844;1;1;1;1;1;1;0;0;1;1;0;0,,,4321583677327450765
orig.piece:5,1;0;0;0;1;1;843;843;843;1;1;1;1;1;1;0;0;1;1;0;0,64.0,;,4321113141090630389

import pandas as pd
import numpy as np

orig = pd.read_csv('orig.piece')
orig.dtypes
Unnamed: 0 int64
aa object
act float64
...
...
s_act float64
dtype: object

>orig['s_act'].head(6)
0 NaN
1 4.321584e+18
2 4.321974e+18
3 4.321494e+18
4 4.321283e+18
5 4.321113e+18
Name: s_act, dtype: float64

>orig['s_act'].fillna(0).astype(int).head(6)
0 0
1 4321583677327450880
2 4321973950881710336
3 4321493786516159488
4 4321282586859217408
5 4321113141090630400

>orig.to_csv('convert.piece')

grep -e 321583677327450 -e 321113141090630 orig.piece convert.piece
orig.piece:1,1;0;0;0;1;1;3844;3844;3844;1;1;1;1;1;1;0;0;1;1;0;0,,,4321583677327450765
orig.piece:5,1;0;0;0;1;1;843;843;843;1;1;1;1;1;1;0;0;1;1;0;0,64.0,;,4321113141090630389
convert.piece:1,1;0;0;0;1;1;3844;3844;3844;1;1;1;1;1;1;0;0;1;1;0;0,,,4.321583677327451e+18
convert.piece:5,1;0;0;0;1;1;843;843;843;1;1;1;1;1;1;0;0;1;1;0;0,64.0,;,4.3211131410906304e+18

你能帮我理解为什么read_csv混淆了最后三位数?它甚至不是舍入问题,数字是完全不同的(如4321583677327450765变为4321583677327450880)是否因为科学记数法的出现 - 我们如何禁用它并让pandas将此数据视为jus对象/字符串或计划整数/浮?

2 个答案:

答案 0 :(得分:3)

它的浮点错误。由于s_act列具有缺失值(pandas不具有整数缺失值),因此它使用dtype = float读取s_act(dtypes在pandas中的列级别定义)。因此,您基本上可以看到以下内容:

>>> x = 4321113141090630389
>>> float(x)
4.32111314109063e+18
>>> int(float(x))
4321113141090630144

就解决方案而言,您可以在读取时将s_act的dtype更改为字符串(生成的dtype将为oject)。例如:

data = """
id,val,x
1,4321113141090630389,4
2,,5
3,200,4
"""

df = pd.read_csv(StringIO(data),header=True,dtype={'val':str})
print df

   id                  val  x
0   1  4321113141090630389  4
1   2                  NaN  5
2   3                  200  4

print df.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 3 entries, 0 to 2
Data columns (total 3 columns):
id     3 non-null int64
val    2 non-null object
x      3 non-null int64

df['val'] = df['val'].fillna(0).astype(int)
print df

   id                  val  x
0   1  4321113141090630389  4
1   2                    0  5
2   3                  200  4

答案 1 :(得分:0)

excel读取大量数字是一个问题。一种选择是通过添加空格来更改数字的格式。在这种情况下,我要在每5个数字之间添加一个空格。

def spaces_in_string(val):    
    try:
        return (' ').join(re.findall('.{1,5}',val))
    except:
        return val

df['col'] = df['col'].apply(spaces_in_string)