在文本文件Python中读取混合数据类型

另一个软件提供了一些“报告”,其中包含我需要使用的数据.该文件非常简单.它的描述行以#开头,即变量名/描述.在下一行后跟逗号分隔的数据.

例如

    #wavelength,'<a comment describing the data>'
    400.0,410.0,420.0, <and so on>
    #reflectance,'<a comment describing the data>'
    0.001,0.002,0.002, <and so on>
    #date,'time file was written'
    2012-03-06 13:12:36.694597  < this is the bit that stuffs me up!! >

当我第一次输入一些代码时,我希望所有数据都将被读取为浮点数.但是我发现了一些日期和字符串.就我的目的而言,我只关心应该是浮点数数组的数据.我读过的所有其他内容(例如日期)都可以视为字符串(即使从技术上讲它们是日期).

我的第一次尝试-一直有效直到发现非浮点数-基本上都忽略了#,然后抓住了字符,继续进行操作,并使用它刚读过的Key创建了字典.然后,我将逗号分隔并在行上堆叠二维数据,从而使键的条目成为数组.类似于下一部分代码.

    data = f.readlines()
    dataLines = data.split('\n')

    for i in range(0,len(dataLines)-1):
        if dataLines[i][0] == '#':
            key,comment = dataLines[i].split(',')
            keyList.append(key[1:])
            k+=1
        else: # it must be data
            d+=1
            dataList.append(dataLines[i])

        for j in range(0,len(dataList)):
            tmp = dataList[j]

            x = map(float,tmp.split(','))
            tempData = vstack((tempData,asarray(x)))

    self.__report[keyList[k]] = tempData  

当我在文件中发现非浮点时,“ x = map(float,tmp.split(‘,’))”行失败(数据行中没有逗号).我以为我会尝试使用isinstance来测试它是否是字符串,但文件读取器会将来自文件的所有数据视为字符串(当然).我试图将行从文件转换为float数组,以为如果失败,则将其视为字符串数组-这样.

     try:
         scipy.array(tmp,dtype=float64)  #try to convert
         x = map(float,tmp.split(','))

     except:# ValueError: # must be a string
         x = zeros((1,1))
         x = asarray([tmp])
         #tempData = vstack((tempData,asarray(x)),dtype=str)
         if 'tempData' in locals():
             pass
         else:
             tempData = zeros((len(x)))

         tempData = vstack((tempData,asarray(x)))

但是,这导致所有内容都作为字符数组读取,因此,我无法将数据索引为numpy数组.所有数据都存在于字典中,但dtype例如为s | 8.似乎try块直接进入了异常.

我希望您能得到建议,以便可以区分浮点数和字符串.在获取报告之前,我不知道数据的顺序.

而且,大文件可能需要很长时间才能加载到内存中,因此,任何有关如何提高效率的建议都将受到赞赏.

谢谢

解决方法:

我假设最终您对x感兴趣,该x的格式应为[400.0、410.0、420.0].

解决此问题的一种方法是在两个不同的语句中分隔按命令拆分和转换为浮点运算,以便在获取字符串元素而不是float或int时可以捕获ValueError.

keyList = []
dataList = []
with open('sample_data','r') as f:
    for line in f.readline():
        if line.startswith("#"):
            key, comment = line.split(',')
            keyList.append(key[1:])
        else: # it must be data
            dataList.append(line)

for data in dataList:
    data_list = data.split(',')
    try:
        x = map(float, data_list)
    except ValueError:
        pass

还要注意我对您的代码所做的其他细微更改,这实际上使它变得更加pythonic.

上一篇:我如何索引4列的n套以使用matplotlib绘制多个图?


下一篇:python-来自*示例的Gauss-Newton方法的实现