Как я могу исправить эту ошибку форматирования в данных ASCII или правильно прочитать данные с помощью Python? - PullRequest
1 голос
/ 27 сентября 2019

Я читаю большие файлы ASCII в python, содержащие данные о выбросах для некоторых атмосферных соединений.Я читаю данные из столбца, используя следующую функцию, которая возвращает список, содержащий значения в столбце:

def get_col(col):
    f = open(file_name, 'r')
    col_data = []
    # Loop over lines and extract column of interest
    for line in f:
        line = line.strip()
        columns = line.split()
        col_data.append(float(columns[col]))
    f.close()
    return col_data

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

17  127 15  3.61    0   0   0   3.61    0   0   0   0   0   0

17  128 15  3.61    0   0   0   3.61    0   0   0   0   0   0

17  129 15  11.1    2 0.0   0 0.0   0 2.1   2 3.6   4 0.0   1 0.0   0 0.0   0 4.7   3 0.6   2 0.00

17  130 15  11.1    2 0.0   0 0.0   0 2.1   2 3.6   4 0.0   1 0.0   0 0.0   0 4.7   3 0.6   2 0.00

Correct row 4: 

17  130 14  11.12   0.00  0.00  2.12  3.64  0.01  0.01  0.00  4.73  0.62  0.00

В этих последних двух строках значения в столбцах 1-3 по-прежнему верны, но начиная с четвертого столбцадополнительный пробел включается между первым и вторым десятичным знаком каждого значения.Это, конечно, приводит к ошибкам при чтении данных.

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

Редактировать: Ссылка на данные: https://github.com/AartZwaan/CO_data

Ответы [ 3 ]

1 голос
/ 27 сентября 2019

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

re.sub(r"(\.\d*)\s*(\d\s{1}\S)", r'\1\2', correct_line)

, например, при вводе:

correct_line = "17  128 15  3.61    0   0   0   3.61    0   0   0   0   0   0"
wrong_line = "17  130 15  11.1    2 0.0   0 0.0   0 2.1   2 3.6   4 0.0   1 0.0   0 0.0   0 4.7   3 0.6   2 0.00"

с правильной строкой ,ничего не изменилось:

re.sub(r"(\.\d*)\s*(\d\s{1}\S)", r'\1\2', correct_line)
# '17  128 15  3.61    0   0   0   3.61    0   0   0   0   0   0'

после разделения стало следующим списком:

['17', '128', '15', '3.61', '0', '0', '0', '3.61', '0', '0', '0', '0', '0', '0']

с неправильной строкой вместо этого мы имеем:

re.sub(r"(\.\d*)\s*(\d\s{1}\S)", r'\1\2', wrong_line)
# '17  130 15  11.12 0.00 0.00 2.12 3.64 0.01 0.00 0.00 4.73 0.62 0.00'

, который когда-то разделился, стал следующим списком:

['17', '130', '15', '11.12', '0.00', '0.00', '2.12', '3.64', '0.01', '0.00', '0.00', '4.73', '0.62', '0.00']
0 голосов
/ 27 сентября 2019

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

17      217     20.     1 0.2     1 0   .10 0.0

Я бы предложил использовать это регулярное выражение, чтобы исправить строку и сохранить тот же формат (с таблицами между каждымстолбец)

correct_line = re.sub(r"\t[\d\.]+ {1}", lambda t: t.group(0).strip()+'\t' , line)
0 голосов
/ 27 сентября 2019

Я думаю, вы можете просто удалить пробелы (но не вкладки) в исходном файле.Если вы работаете в Unix-подобной системе, вы можете просто запустить

sed -i.bkp 's/ //g' gridCO

Тогда ваша программа сможет ее проанализировать.

EDIT

Используя только Python, вы можетеизменить первую строку внутри цикла for:

line = line.strip()

in

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