Как автоматизировать удаление переменного количества лишних строк в файлах данных?

#python

Вопрос:

Я использую филогенетическую программу Bayestraits, которая создает очень большие выходные файлы (более 10 000 000 строк для тысяч столбцов), поэтому я хочу обрабатывать файлы автоматически, не открывая их. Выходные файлы представляют собой текстовые файлы с пробелами, разделяющими столбцы (при наличии). Кроме того, выходные файлы могут содержать сотни строк дескрипторов до фактического начала обработки данных, которые необходимо удалить для анализа данных.

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

начало
дополнительной строки 1
Дополнительная строка 2
A .B . C D #заголовки фактических данных
1 30 34 3 #первая строка фактических данных
2 33 30 3
3 31 39 4
4 28 42 2
5 25 37 4

В этом простом случае необходимо удалить только первые три строки, но в моих случаях это переменное количество строк в диапазоне от ~200 до ~800.

Первый заголовок всегда «Итерация» («A» в моем фиктивном наборе данных), но слово «итерация» обычно также появляется в дополнительных строках, предшествующих данным, и количество «дополнительных» строк перед данными может варьироваться. Существует ли простой способ преобразования многих похожих текстовых файлов в файлы .csv, которые не содержат строк, предшествующих заголовкам и данным?

Я активно пытался сделать это на python, но я новичок в этом типе кодирования, и у меня возникли проблемы с началом работы. До сих пор я мог использовать sed для преобразования файлов из .txt в .csv, но не смог продвинуться дальше, используя:

 $ sed -r 's/[[:blank:]] /,/g' input.txt > output.csv
 

Большое вам спасибо за любую обратную связь или помощь, я уверен, что это довольно простое решение, но я уже некоторое время пытаюсь в нем разобраться.

Ответ №1:

Возможно, вам лучше загрузить файл в виде обычного текстового файла, предварительно обработать его, затем преобразовать в фрейм данных pandas и, наконец, сохранить его в формате csv.

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

 with open("file.txt") as f:
   lines = f.readlines()
 

Затем вы можете выполнить итерацию и посмотреть, где начинаются числовые данные

 data_start = 0
for index, data in enumerate(lines):
    try: 
        num = int(data.split(" ")[0])         # attempt type coercion        
    except ValueError:
         continue               # move on to next
    else:
        data_start = index - 1  # this will include column titles
        break
 

Затем установите оставшийся список в фрейм данных pandas и сохраните его в формате csv

 import pandas as pd

df = pd.DataFrame(lines[data_start:], columns=lines[0])
df.to_csv("file.csv", index=False)   # unless you want to keep the index
 

Комментарии:

1. Не используйте голый импорт ( PEP8 ). Самое большее, перехватывайте все исключения, не связанные с выходом except Exception . Хотя в этом случае вы точно знаете, какое исключение должно быть поймано, то есть ValueError . Кроме того, ограничьте try блок только той строкой, которая должна вызвать исключение.

2. Другое дело, не будет ли приведение типов всегда завершаться ошибкой, если в строке есть что-то еще, кроме одного непрерывного целого числа (что, похоже, имеет место)? Я внес предложение, чтобы решить эту проблему.

3. Хороший улов. Договорились по всем счетам.