如何用Pandas将特定格式的.log日志文件转换为.csv文件?
解决特定格式学生日志的Pandas解析问题
看起来你在解析固定格式的学生日志时遇到了麻烦,核心问题在于你的代码依赖了日志中不存在的[]分隔符,而且字段拆分逻辑没有匹配日志的实际结构。咱们一步步来修正这个问题:
1. 先明确日志的固定结构
先拿你提供的日志样本拆解清楚每个字段的边界:
33 HEIGHT 5 5 INFO ABSENT FROM SCHOOL 123 He has been absent for 48 hours NOLAN Time:2020-07-14 12:34:08 PAUL
对应字段:
COUNT: 开头的数字33HEIGHT:HEIGHT后的两个数字5 5→ 合并为浮点数5.5MESSAGE_TITLE: 从INFO到123的部分INFO ABSENT FROM SCHOOL 123BODY: 中间的描述语句He has been absent for 48 hoursSCHHO: 时间字段前的名字NOLANDATETIME: 带Time:前缀的时间字符串2020-07-14 12:34:08NAME: 最后的名字PAUL
2. 精简并修正代码依赖
你的代码导入了很多用不到的库(比如wx、JSON、matplotlib),先精简到必要的工具:
import pandas as pd import re from datetime import datetime
3. 用正则表达式精准匹配字段
因为日志结构固定,正则表达式是最可靠的拆分方式。我们可以写一个匹配整行日志的正则模式,每个分组对应一个字段:
# 定义正则模式,每个括号对应一个字段 log_pattern = r'^(\d+) HEIGHT (\d+) (\d+) (.+?) ([A-Za-z\s]+?) (\w+) Time:(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+)$'
4. 逐行解析日志并构建DataFrame
接下来读取日志文件,逐行匹配正则,提取并处理每个字段:
# 初始化存储各字段的列表 count_list = [] height_list = [] title_list = [] body_list = [] school_list = [] dt_list = [] name_list = [] # 读取日志文件 with open('STUDENT_PROFILE.log', 'r') as f: for line in f: line = line.strip() if not line: continue # 跳过空行 # 匹配正则模式 match_result = re.match(log_pattern, line) if match_result: # 提取每个分组的内容 count = match_result.group(1) height_part1 = match_result.group(2) height_part2 = match_result.group(3) message_title = match_result.group(4) body_content = match_result.group(5).strip() school_name = match_result.group(6) dt_string = match_result.group(7) student_name = match_result.group(8) # 处理HEIGHT为浮点数 height = float(f"{height_part1}.{height_part2}") # 处理时间为datetime对象 dt = datetime.strptime(dt_string, '%Y-%m-%d %H:%M:%S') # 添加到对应列表 count_list.append(count) height_list.append(height) title_list.append(message_title) body_list.append(body_content) school_list.append(school_name) dt_list.append(dt) name_list.append(student_name) # 构建DataFrame df = pd.DataFrame({ 'COUNT': count_list, 'HEIGHT': height_list, 'MESSAGE_TITLE': title_list, 'BODY': body_list, 'SCHHO': school_list, 'DATETIME': dt_list, 'NAME': name_list }) # 计算时间差(相对于第一条日志的时间) df['delta_t'] = df['DATETIME'] - df['DATETIME'].iloc[0] df['delta_t_seconds'] = df['delta_t'].dt.total_seconds() # 保存到CSV df.to_csv('test_log.csv', index=False)
5. 调试小技巧
- 如果有日志行匹配失败,可以添加
else分支打印不匹配的行,方便排查格式问题:else: print(f"无法匹配的日志行: {line}") - 如果
BODY字段包含特殊字符(比如标点),可以调整正则中的([A-Za-z\s]+?)为(.+?),但要确保它不会匹配到后面的SCHHO字段(因为SCHHO是大写名字,正则会优先匹配到第一个大写单词前的内容)
内容的提问来源于stack exchange,提问作者Greatpomps
相关产品推荐
相关产品推荐

