Python-Не удается преобразовать строку в число с плавающей точкой ... манипулирование текстовым файлом - PullRequest
1 голос
/ 01 ноября 2011

Для всех:

У меня есть вопрос о преобразовании строки в число с плавающей точкой в ​​python и любые советы, которые вы можете дать о моем коде.

Я думаю, что лучший способ показать вам мою проблему - это объяснить, что я делаю.

У меня есть текстовый файл, сгенерированный из программы на фортране. Этот текстовый файл имеет форму:

 0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000
 0.000
 0.500     0.156     0.154     0.152     0.151     0.148     0.144     0.141     0.138     0.135     0.132     0.130     0.127     0.124     0.121     0.118     0.115     0.112     0.110     0.107     0.104     0.102     0.100     0.097     0.093     0.089     0.087     0.084     0.082     0.079     0.076     0.074     0.072     0.069     0.067     0.064     0.063     0.060     0.058     0.056     0.054     0.052     0.051     0.049     0.044     0.041     0.038     0.036     0.034     0.031     0.029     0.027     0.026     0.024     0.022     0.020     0.018     0.016     0.015     0.013     0.012     0.010     0.009     0.007     0.006     0.004     0.003     0.002     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000     0.000
 0.000

Первое значение 0.0 - это время, второе значение - это высота воды в ячейке 1 и т. Д. В настоящее время во время обработки после 100 входных данных создается новая строка и при каждом новом времени создается новая строка. Я хотел бы иметь возможность написать код Python, чтобы он выглядел так:

time1     cell1     cell2     .....
time2     cell1     cell2     .....

Следует иметь в виду, что число ячеек будет меняться, и после каждых 100 создается новая строка. (Мой пример выше дает только время и 100 ячеек в качестве демонстрации.)

Мой код ниже ..

    from pylab import *
    from numpy import *
    import math

    ########################

    a=open('wh.txt','r')
    b=open('new.txt', 'w')

    for line in a:
      b.write(line.lstrip())

    c=open('new.txt','r')
    d=open('newer.txt','w')

    for line in c:
      d.write(line.replace('\n','     '))

    e=loadtxt('newer.txt')
    o=open('newest.txt','w')



    ### v = value to split, l = size of each chunk
    h = lambda v, l: [v[i*l:(i+1)*l] for i in range(int(math.ceil(len(v)/float(l))))]

    g=list(h(tuple(e),102))


    with open("newest.txt","w") as o:
        o.write('\n'.join(map(str,g)))

Это дает вывод в виде кортежа:

(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
(    0.5, 0.156, 0.154, 0.152, 0.151, 0.14799999999999999, 0.14399999999999999, 0.14099999999999999, 0.13800000000000001, 0.13500000000000001, 0.13200000000000001, 0.13, 0.127, 0.124, 0.121, 0.11799999999999999, 0.115, 0.112, 0.11, 0.107, 0.104, 0.10199999999999999, 0.10000000000000001, 0.097000000000000003, 0.092999999999999999, 0.088999999999999996, 0.086999999999999994, 0.084000000000000005, 0.082000000000000003, 0.079000000000000001, 0.075999999999999998, 0.073999999999999996, 0.071999999999999995, 0.069000000000000006, 0.067000000000000004, 0.064000000000000001, 0.063, 0.059999999999999998, 0.058000000000000003, 0.056000000000000001, 0.053999999999999999, 0.051999999999999998, 0.050999999999999997, 0.049000000000000002, 0.043999999999999997, 0.041000000000000002, 0.037999999999999999, 0.035999999999999997, 0.034000000000000002, 0.031, 0.029000000000000001, 0.027, 0.025999999999999999, 0.024, 0.021999999999999999, 0.02, 0.017999999999999999, 0.016, 0.014999999999999999, 0.012999999999999999, 0.012, 0.01, 0.0089999999999999993, 0.0070000000000000001, 0.0060000000000000001, 0.0040000000000000001, 0.0030000000000000001, 0.002, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)

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

Ответы [ 2 ]

0 голосов
/ 02 ноября 2011

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

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

def unwrap_data(filename, wrap_len=101, map_func=None):
    """
    Generator which reads a file and returns a list of float,
    one for each data row.

    Rows in the file are assumed to be wrapped after every 
    wrap_len columns, so we unwrap it before returning each
    data row.

    wrap_len defaults to 101 (1 time column + 100 cell values).

    Caveat: If a timing data has exactly 100 cell values (101 
    columns), the output of this function will be wrong unless
    an additional newline exists before the next timing row, e.g.

         time1      cell1_1    cell1_2  ... cell1_100
         cell1_101  cell1_102  ...
         time2      cell2_1    cell2_2  ... cell2_100

         time3      cell3_1    cell3_2  ...
    """
    next_data = []
    for line in open(filename, 'r'):  # for each line in file
        L = line.strip().split()
        if map_func:
            L = map(map_func, L)  # run map_func() on each list element
        next_data.extend(L)  # add to prev row
        if len(L) != wrap_len and next_data: 
            # the line was not wrapped, assume new timing data
            # "and next_data" will avoid returning empty lists for blank lines
            yield next_data
            next_data = []

Я определил ее как функцию генератора , чтобы повысить четкость и производительность.

Пример использования:

Чтобы распечатать проанализированный вывод в новый файл в виде записей, разделенных табуляцией:

out = open("outfile.dat", "w")
for line in unwrap_data("input_file.dat"):
    out.write("\t".join(line) + "\n")

Обратите внимание, что функция возвращает список строковых значений. Чтобы использовать значения как число с плавающей точкой, используйте аргумент map_func.

В следующем примере мы передаем функцию float(), чтобы каждая запись преобразовывалась в число с плавающей точкой. Затем мы печатаем time (первый столбец) и минимальное / максимальное значение ячейки (оставшиеся столбцы).

for line in unwrap_data("input_file.dat"):
    print line[0], min(line[1:]), max(line[1:])

Я также параметризовал длину обтекания, чтобы вы могли изменить ее, добавив аргумент wrap_len=<new_value> при вызове функции.

Надеюсь, эта помощь.

0 голосов
/ 02 ноября 2011

Самая большая проблема, с которой вы столкнетесь, - убедиться, что вы можете определить разницу между состояниями.Как кто-то еще указал, откуда вы знаете, что у вас нет времени и 99 ячеек или дополнительных 100 ячеек, перенесенных с предыдущей строки?

Я бы начал с попытки найти что-то уникальноео данных, чтобы иметь возможность дифференцировать его.Есть ли диапазон значений, которые имеют смысл на ячейку?Конечно, это не самый безопасный способ справиться с этим, но если то, что вы показали о данных, - это все, что нужно, я не уверен, какие еще есть варианты.

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

Надеюсь, это хотя бы подтолкнет вас вправильное направление.

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