2013-07-11 2 views
2

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

Some random text 
more random text that may be of different length 
JUNK 0 9 8 
GOOD 0 1 1 
GOOD 5 5 5 
more random text interdispersed 
GOOD 123 321 2 
JUNK 55 1 9 
GOOD 1 2 3 

Файл ограничен пространством. Мне только нравятся строки, начинающиеся с «GOOD», которые будут иметь одинаковое форматирование.

Я считаю, что read_table() - это правильная команда, но я не знаю, как ее фильтровать.

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

ответ

4

Вам не нужно регулярное выражение для соответствия строкам, начинающимся с «GOOD». Просто итерацию по файлу и выбросить все остальные линии, создавая «чистую» копию данных, которые вы хотите:

with open('irregular.txt') as inFile, open('regular.txt', 'w') as outFile: 
    for line in inFile: 
     if line.startswith('GOOD'): 
      outFile.write(line) 

Тогда вы можете прочитать «regular.txt» с помощью read_table или read_csv с delim_whitespace=True аргументом.

+0

Это будет большая проблема скорости, потому что я открываю тысячи файлов в директории с десятками из тысяч файлов. Я хочу избежать промежуточного письма и чтения, если это вообще возможно. У меня возникает соблазн подумать, что моя текущая реализация быстрее, чем эта. – deltap

+1

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

2

Позволяет сделать генератор, который фильтрует хорошие линии

def generate_good_lines(filename): 
    with open(filename) as f: 
     if line.startswith('GOOD'): 
      yield line 

Теперь все, что вам нужно разобрать эти строки в пути вы хотите, например:

def generate_parsed(filename_list): 
    for filename in filename_list: 
     for line in generate_good_lines(filename) 
      data = your_parser_function(line) 
      yield data 

Тогда вы потребляете все строки в списке (для пример):

your_list = list(generate_parsed(your_filename_list)) 

в вашем вопросе он выглядит как your_parser_function выглядит следующим образом:

def your_parser_function(line): 
    return map(int, line[5:].split()) # split values and convert them to integers 

генераторы заботиться о вашей памяти и процессорного времени потребления

/извините за мой английский/

Смежные вопросы