читать смешанные типы данных в текстовом файле Python - PullRequest
3 голосов
/ 06 марта 2012

Мне дали несколько «отчетов» из другого программного обеспечения, содержащего данные, которые мне нужно использовать. Файл довольно прост. У него есть строка описания, которая начинается с #, который является именем / описанием переменной. За ними следуют разделенные запятыми данные в следующей строке.

например

    #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!! >

Когда я впервые набрал какой-то код, я ожидал, что все данные будут считаны как плавающие. Но я обнаружил некоторые даты и строки. Для моих целей все, что меня волнует, это данные, которые должны быть массивами с плавающей точкой. Все остальное, что я читаю (например, даты), можно рассматривать как строки (даже если они технически, например, дата).

Моя первая попытка - которая работала до тех пор, пока я не нашел non-float - в основном игнорирует символ #, а затем захватывает символы, после чего создает словарь с ключом, то есть символами, которые он только что прочитал. Затем я сделал запись для ключа массивом, разделив запятые и сложив строки для двумерных данных. Аналогично следующему разделу кода.

    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  

Когда я нахожу non-float в моем файле, строка "x = map (float, tmp.split (','))" завершается неудачно (в строке данных нет запятых). Я думал, что попробую проверить, является ли она строкой или не использует isinstance, но программа чтения файлов обрабатывает все данные, поступающие из файла, как строку (конечно). Я попытался преобразовать строку из файла в массив с плавающей точкой, подумав, что если это не удастся, то просто обработайте его как массив строк - вот так.

     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)))

Это, однако, приводит к тому, что ВСЁ читается как массив символов, и поэтому я не могу индексировать данные как пустой массив. Все данные есть в словаре, но dtype, например, s | 8. Кажется, что блок try идет прямо к исключению.

Буду признателен за любой совет, как заставить это работать, чтобы я мог различать поплавки и строки. Я не знаю порядок данных до получения отчета.

Кроме того, большие файлы могут загружаться в память довольно долго, также приветствуются любые советы о том, как сделать это более эффективным.

Спасибо

Ответы [ 2 ]

3 голосов
/ 06 марта 2012

Я предполагаю, что, наконец, вы заинтересованы в x, который должен быть в формате [400.0, 410.0, 420.0].

Один из способов справиться с этим - разделение деления по команде и преобразование в операции с плавающей запятой вдва разных оператора, так что вы можете поймать ValueError, когда получите строковые элементы вместо float или int.

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

Также обратите внимание на другие незначительные изменения, которые я сделал в вашем коде, которыеделает его более питонным по своей природе.

0 голосов
/ 06 марта 2012

это может быть глупым предложением, но не могли бы вы просто сделать дополнительную проверку

if ',' in dataLines[i]

перед добавлением строки в список данных? Или, если нет, написать регулярное выражение для проверки списка чисел с плавающей запятой через запятую?

(\d(\.\d+)?)(,\d(\.\d+)?)*

может сделать трюк (тоже допускает целые числа).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...