2016-10-31 4 views
1

У меня есть сложный файл журнала, который я хочу получить в чистый DF. Формат журнала следующий:чтение журнала с пунктирными линиями в файл данных pandas

=============================================================================== 
2016/03/28 12:26:45 - Message 
------------------------------------------------------------------------------- 
2016/03/28 12:26:45 - Message 
2016/03/28 12:26:45 - Message 
Message 
2016/03/28 12:26:45 - Message 
2016/03/28 12:26:46 - Message 
2016/03/28 12:26:46 - Message 
2016/03/28 12:28:30 - Message 
2016/03/28 12:28:40 - Message 
2016/03/28 12:28:40 - Message 
2016/03/28 12:28:40 - Message 
------------------------------------------------------------------------------- 
2016/03/28 12:28:40 - Message 
=============================================================================== 

Журнал продолжается в приведенном выше шаблоне, моя цель состоит в том, чтобы иметь следующую структуру данных;

Time     Text 
2016/03/28 12:26:45 Message 

Я устал, чтобы разобрать файл файла на «-» и создать Dataframe и удалить пунктирные линии.

import pandas as pd 
from pandas.compat import StringIO 

clean = open(filename).read().remove('-------------------------------------------------------------------------------', '') 
clean2 = open(filename).read().replace('===============================================================================', '') 
df = pd.read_csv(filename, sep = "\s*\-", names = ["Time", "Text"], engine = "python") 
df.Time = pd.to_datetime(df.Time, format='%d/%m/%y %H:%M:%S.%f') 
df.Text = df.Text 

Однако я получаю много столбцов NaN, любая помощь приветствуется

+0

Двойные пунктирные линии находятся только в начале файла и в конце файла? – jezrael

+0

Они находятся в начале и в конце каждого раздела, поэтому в файле журнала есть много экземпляров двойных тире файлов, файл журнала следует шаблону, который я указал в сообщении, так что этот шаблон происходит несколько раз в файле @jezrael – ukbaz

ответ

2

Я думаю, что вы можете использовать to_datetime с errors='coerce' для замены некорректных данных в NaT с dropna для Вытащите все строки, в которых NaT в колонке Time:

import pandas as pd 
from pandas.compat import StringIO 

temp=u"""=============================================================================== 
2016/03/28 12:26:45 - Message 
------------------------------------------------------------------------------- 
2016/03/28 12:26:45 - Message 
2016/03/28 12:26:45 - Message 
Message 
2016/03/28 12:26:45 - Message 
2016/03/28 12:26:46 - Message 
2016/03/28 12:26:46 - Message 
2016/03/28 12:28:30 - Message 
2016/03/28 12:28:40 - Message 
2016/03/28 12:28:40 - Message 
2016/03/28 12:28:40 - Message 
------------------------------------------------------------------------------- 
2016/03/28 12:28:40 - Message 
===============================================================================""" 
#after testing replace StringIO(temp) to filename 
df = pd.read_csv(StringIO(temp), sep="\s+-\s+", names = ["Time", "Text"], engine = "python") 

df.Time = pd.to_datetime(df.Time, errors='coerce') 
df.dropna(subset=['Time'], inplace=True) 
print (df) 
        Time  Text 
1 2016-03-28 12:26:45 Message 
3 2016-03-28 12:26:45 Message 
4 2016-03-28 12:26:45 Message 
6 2016-03-28 12:26:45 Message 
7 2016-03-28 12:26:46 Message 
8 2016-03-28 12:26:46 Message 
9 2016-03-28 12:28:30 Message 
10 2016-03-28 12:28:40 Message 
11 2016-03-28 12:28:40 Message 
12 2016-03-28 12:28:40 Message 
14 2016-03-28 12:28:40 Message 
+0

wow, который отлично работает. Можете ли вы объяснить sep = "\ s + - \ s +" и pd.to_datetime (df.Time, errors = 'coerce?), Заключается в том, чтобы избавиться от сообщения в столбце времени? спасибо – ukbaz

+1

'sep =" \ s + - \ s + "' означает, что разделитель представляет собой несколько пробелов с '-', а затем также несколько пробелов. И при добавлении параметра 'errors = 'coerce')' все данные, которые не могут быть проанализированы, заменяются на 'NaT' (это' NaN' для datetime). Поэтому для последнего нужно всего лишь отбросить все строки, где находятся значения «NaT» в столбце. – jezrael

2

Более длительная альтернатива очень хорошее решение @jezrael является следующее:

import pandas as pd 

infile = "test.txt" #this is your file 

df = pd.DataFrame(columns=['Time','Text']) 

with open(infile, "r") as inf: 
    for i, line in enumerate(inf): 
     line = line.strip() 
     if line.startswith("-") or line.startswith("="): 
      pass 
     else: 
      if len(line.split("-")) > 1: 
       df.loc[i] = pd.Series({'Time':line.split("-")[0], 'Text':line.split("-")[1]}) 

inf.close() 

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

df.Time = pd.to_datetime(df.Time) 

в конце сценария