我有一个混合浮点数、字符串和整数的 csv 文件,这是 FORTRAN 文件的格式化输出。典型的行如下所示:
507.930 , 24.4097 , 1.0253E-04, O III , 4
我想在保持浮点小数位不变的情况下阅读它,并检查每行中的第一个条目是否存在是另一个列表。
使用 loadtxt 和 genfromtxt 会导致数字位置从 3(或 4)变为 12。
我应该如何解决这个问题?
我有一个混合浮点数、字符串和整数的 csv 文件,这是 FORTRAN 文件的格式化输出。典型的行如下所示:
507.930 , 24.4097 , 1.0253E-04, O III , 4
我想在保持浮点小数位不变的情况下阅读它,并检查每行中的第一个条目是否存在是另一个列表。
使用 loadtxt 和 genfromtxt 会导致数字位置从 3(或 4)变为 12。
我应该如何解决这个问题?
如果您需要精确地保持精度,则需要使用decimal
module。否则,浮点算术限制问题可能会让您失望。
但是,您可能并不真正需要那种精度 - 只要确保您不完全比较float
s 的相等性,而是始终允许一个软糖因素,并将输出格式化为有限数量的有效数字:
# instead of if float1==float2:, use this:
if abs(float1-float2) <= sys.float_info.epsilon:
print "equal"
loadtxt
似乎采取了converters
这样的论点:
from decimal import Decimal
numpy.loadtxt(..., converters={0: Decimal,
1: Decimal,
2: Decimal})
应该管用。
Decimal
's 应该以你需要的任何精度工作,尽管如果你正在做大量的数字运算,Decimal
它会比使用float
. 但是,我假设您只是想在不丢失任何精度的情况下转换数据,所以这应该没问题。
我写完了一些字符串处理代码。不优雅但有效:
stuff=loadtxt(fname1,skiprows=35,dtype="f10,f10,e10,S10,i1",delimiter=',')
stuff2 = loadtxt('keylines.txt') # a list of the reference values
... # open file for writing etc
for i in range(0,len(stuff)):
bb=round(float(stuff[i][0]),3) # gets number back to correct decimal format
cc=round(float(stuff[i][1]),5) # ditto
dd=float(stuff[i][2])
ee=stuff[i][3].replace(" ","") # gets rid of extra FORTRAN spaes
ff=int(stuff[i][4])
for item in stuff2:
if bb == item:
fn.write( str(bb)+','+str("%1.5f" % cc)+','+str("%1.4e" % dd)+','+ee+','+str(ff)+'\n')