Pandas移除含特定值列问题:服务器日志告警文件生成优化
服务器日志处理告警文件生成问题排查与优化
问题现象
处理服务器日志生成独立告警HTML文件时,出现以下异常:
- 生成了多余的HTML文件(预期3个,实际生成4个以上)
- 部分文件未完全移除值为
' - '(带空格的短横线)的列
问题根源
核心问题出在create_html_files函数的逻辑:
- 循环删除列时重复生成文件:每次删除一列后就立即写入HTML文件,导致单个事件被多次拆分输出
- 冗余的数据转换:将DataFrame转列表再用Counter统计属于多余步骤,原
dataframe()函数返回的final已经是去重后的结果
优化后的完整代码
import pandas as pd # 模拟从JSON提取并填充空值的数据 timestamp_list = ['07/11/2023','07/10/2023','07/09/2023'] username_list = ['jsmith','arossi',' - '] host_list = ['10.10.1.100',' - ','10.10.1.300'] file_path_list = ['C:\\Users\\user\\Desktop','C:\\Users\\user\\Desktop',' - '] account_name_list = ['smith','rossi',' - '] def get_processed_df(): # 创建初始DataFrame df = pd.DataFrame({ 'Timestamp': timestamp_list, 'Username': username_list, 'Host': host_list, 'FilePath': file_path_list, 'AccountName': account_name_list }) # 按所有字段分组去重并统计(原逻辑保留,若无需统计可直接返回df) df_sum = df.groupby(df.columns.tolist()) \ .agg(Detections=("Timestamp", len)) \ .reset_index() # 返回去重后的核心字段DataFrame return df_sum[['Timestamp','Username','Host','FilePath','AccountName']] def generate_alert_htmls(df): count = 0 for _, row in df.iterrows(): count += 1 # 将单行转为DataFrame single_row_df = pd.DataFrame([row.values], columns=df.columns) # 一次性移除所有值为' - '的列 cols_to_drop = single_row_df.columns[single_row_df.eq(' - ').any()] cleaned_df = single_row_df.drop(cols_to_drop, axis=1) # 生成HTML文件 with open(f'event{count}.html', 'w', encoding='utf-8') as f: f.write(cleaned_df.to_html(index=False)) # 执行流程 final_df = get_processed_df() generate_alert_htmls(final_df)
优化点说明
- 简化数据流程:去掉多余的
add_to_list和sort_list_items函数,直接基于DataFrame处理,避免数据格式来回转换 - 修复HTML生成逻辑:对单个事件先一次性删除所有目标列,再生成一个HTML文件,解决多余文件问题
- 代码可读性提升:拆分函数职责,
get_processed_df负责数据清洗去重,generate_alert_htmls负责告警文件生成 - 编码规范:添加编码参数
encoding='utf-8'避免中文乱码,设置index=False让HTML表格更简洁
验证结果
生成的3个HTML文件完全符合预期:
- event1.html
<table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th>Timestamp</th> <th>Host</th> </tr> </thead> <tbody> <tr> <td>07/09/2023</td> <td>10.10.1.300</td> </tr> </tbody> </table>
- event2.html
<table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th>Timestamp</th> <th>Username</th> <th>FilePath</th> <th>AccountName</th> </tr> </thead> <tbody> <tr> <td>07/10/2023</td> <td>arossi</td> <td>C:\Users\user\Desktop</td> <td>rossi</td> </tr> </tbody> </table>
- event3.html
<table border="1" class="dataframe"> <thead> <tr style="text-align: right;"> <th>Timestamp</th> <th>Username</th> <th>Host</th> <th>FilePath</th> <th>AccountName</th> </tr> </thead> <tbody> <tr> <td>07/11/2023</td> <td>jsmith</td> <td>10.10.1.100</td> <td>C:\Users\user\Desktop</td> <td>smith</td> </tr> </tbody> </table>
内容的提问来源于stack exchange,提问作者OverflowStack
相关产品推荐
相关产品推荐

