pd.read_csv 的截断问题
我想请教一下关于pandas.read_csv这个功能的问题。我在用pd.to_csv把一个很长的整数存到文件里时,数据保存得很好。但是当我用pd.read_csv把它读回来时,最后三位数字就出错了。当我再用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把这些数据当作普通的对象/字符串或者简单的整数/浮点数来处理呢?
2 个回答
0
这是一个关于Excel读取大数字的问题。解决这个问题的一个方法是通过添加空格来改变数字的格式。在这个例子中,我是在每五个数字之间加一个空格。
def spaces_in_string(val):
try:
return (' ').join(re.findall('.{1,5}',val))
except:
return val
df['col'] = df['col'].apply(spaces_in_string)
3
这是浮点数错误。因为 s_act
这一列有缺失值(pandas中没有整数类型的缺失值),所以它把 s_act
读取为浮点数类型(在pandas中,数据类型是在列级别定义的)。所以你实际上看到的是这样的情况:
>>> x = 4321113141090630389
>>> float(x)
4.32111314109063e+18
>>> int(float(x))
4321113141090630144
至于解决办法,你可以在读取 s_act
时把它的数据类型改成字符串(这样得到的数据类型会是对象)。比如说:
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