- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
**[时间维度]**日志数据提取事件关键词,解析对应时间点计数,matplotlib绘制统计图,python
https://zhangphil.blog.csdn.net/article/details/125914326
https://zhangphil.blog.csdn.net/article/details/125914326
日志或数据文件中,每一行数据均为相对结构化的数据,每一行数据均记录描述了一次事件。该事件的数据中包含特定关键词和时间。
实现一个简单的功能:
(1)数据文件中,对每一行数据模糊查找是否包含了所要寻找的关键词,如果该行以一定的概率(>80%可能性)存在目标关键词,那么该行即为认定为目标高价值数据事件行,然后再从该行中提取事件时间点。
(2)因为数据文件中的行数据时海量的,也意味着高价值事件很多,同样,这条事件对应的时间点也很多。需要把事件发生时间划入到不同的时间段(时间区间),比如(11,12)代表11点到12点,(1,2)代表凌晨1点到2点。每一个时间段内,只要有高价值事件(包含关键词的数据哈)发生的时间落入进来,就为这个时间段计数+1。
(3)这样每个时间段(时间区间)都会有计数统计。比如(9,10),计数5,表示发生再9点到10点(不包含10点)的事件为5件。
(4)最终绘制水平方向的柱状图把统计数据展示。
有些行没有时间或者数据样本残缺不全,需要过滤筛选。
from datetime import datetime
from pprint import pp
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from fuzzywuzzy import fuzz
import re
FILE_PATH = r'源数据的存放路径'
KEY = r'要匹配查找的关键词' # 关键词1,关键词2
threshold = 80
SECTION = 'section'
SUM = 'sum'
def drawchart(df):
myfont = matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\msyh.ttc')
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rc('font', family='YaHei', weight='bold')
order = []
name = []
mem = []
for d, i in zip(df.values, df.index):
order.append(i)
name.append(d[0])
mem.append(int(d[1]))
FONT_SIZE = 12
fig, ax = plt.subplots(figsize=(15, 13))
b = ax.barh(y=range(len(name)), width=mem, align='center', color='red')
# 为横向水平的柱图右侧添加数据标签。
i = 0
for rect in b:
w = rect.get_width()
ax.text(x=w, y=rect.get_y() + rect.get_height() / 2, s='%d' % (int(w)),
horizontalalignment='left', verticalalignment='center',
fontproperties=myfont, fontsize=FONT_SIZE - 2, color='green')
ax.text(x=w / 2, y=rect.get_y() + rect.get_height() / 2, s=str(order[i]),
horizontalalignment='center', verticalalignment='center',
fontproperties=myfont, fontsize=FONT_SIZE - 3, color='white')
i = i + 1
ax.set_yticks(range(len(name)))
ax.set_yticklabels(name, fontsize=FONT_SIZE - 1, fontproperties=myfont)
ax.invert_yaxis()
ax.set_xlabel('数据', fontsize=FONT_SIZE + 2, fontproperties=myfont)
ax.set_title('不同时间段的数据点总量排名', fontsize=FONT_SIZE + 5, fontproperties=myfont)
# 不要横坐标上的label标签。
plt.xticks(())
# 清除四周的边框线
ax.get_yaxis().set_visible(True)
for spine in ["left", "top", "right", "bottom"]:
ax.spines[spine].set_visible(False)
plt.subplots_adjust(left=0.15) # 调整左侧边距
# ax.margins(y=0.01) #缩放 zoom in
ax.set_aspect('auto')
plt.show()
def read_file():
file = open(FILE_PATH, 'r', encoding='UTF-8')
all_case_time = []
case_count = 1
cnt = 1
for line in file:
pr = fuzz.partial_ratio(line, KEY)
if pr >= threshold:
print('-----')
print(f'第{case_count}件')
case_count = case_count + 1
try:
# 正则匹配 xxxx年xx月xx日xx时xx分
mat = re.search(r'\d{4}\年\d{1,2}\月\d{1,2}\日\d{1,2}\时\d{1,2}\分', line)
t_str = mat.group().replace('\n', '') # 去掉正则匹配到但是多余的 \n 换行符
try:
object_time = datetime.strptime(t_str, "%Y年%m月%d日%H时%M分")
all_case_time.append(object_time.time()) # 把时间从日期中提取出来,放到数组中
print(f'时间{object_time.time().strftime("%H:%M")}')
except:
print('解析日期失败')
pass
except:
t_str = '-解析异常-'
pass
s = '第{number}行,相似度{ratio},时间{case_time}\n{content}'
ss = s.format(number=cnt, ratio=pr, case_time=t_str, content=line)
pp(ss)
# 快速调试
# if case_count > 100:
# break
cnt = cnt + 1
file.close()
return all_case_time
def data_frame():
ts = read_file()
times = []
for i in range(24):
times.append({SECTION: (i, i + 1), SUM: 0})
for t in ts:
for tx in times:
if tx[SECTION][0] <= t.hour < tx[SECTION][1]:
tx[SUM] = tx[SUM] + 1
# pprint(f'{t.strftime("%H:%M")} @ {tx[SECTION]}')
break
return times
if __name__ == '__main__':
times = data_frame()
# 数据组装成pandas数据帧。
pd_data = []
for t in times:
l = [t[SECTION], t[SUM]]
pd_data.append(l)
col = ['时间段', '时间点次数']
df = pd.DataFrame(data=pd_data, columns=col)
df = df.sort_values(by=col[1], axis=0, ascending=False) # 降序
# 重置索引
df = df.reset_index(drop=True)
df.index = df.index + 1
# 前20名
pp(df.head(20))
# pp(df.values)
drawchart(df)
部分输出:
时间段 时间点次数
1 (20, 21) 116
2 (21, 22) 115
3 (19, 20) 86
4 (22, 23) 80
5 (23, 24) 56
6 (13, 14) 56
7 (15, 16) 48
8 (14, 15) 45
9 (0, 1) 41
10 (18, 19) 36
11 (16, 17) 27
12 (17, 18) 26
13 (12, 13) 23
14 (1, 2) 16
15 (11, 12) 15
16 (2, 3) 12
17 (10, 11) 11
18 (9, 10) 9
19 (8, 9) 9
20 (4, 5) 5
变换不同的关键词,生成的统计图:
我无法在此图中定位轴标签。我喜欢放置顶部标签,使管道与网格对齐,并放置左右标签,以便它们不接触绘图。 我试过了 ax.tick_params(axis='both', which='both'
我使用的是 python 2,下面的代码只是使用了一些示例数据,我的实际数据可能有不同的长度,并且可能不是很细。 import numpy as np import datetime i
给定坐标 [1,5,7,3,5,10,3,6,8]为 matplotlib.pyplot ,如何突出显示或着色线条的不同部分。例如,列表中的坐标 1-3 ( [1,5,7,3] ) 表示属性 a .我
我正在matplotlib中绘制以下图像。 我的问题是,图像看起来像这样,但是,我想使背景变暗,因为当我打印该图像时,灰度部分不会出现在打印物中。有人可以告诉我API进行此更改吗? 我使用简单的API
这是关于matplotlib的一个非常基本的问题,但是我不知道该怎么做: 我想绘制多个图形,并使用绘制窗口中的箭头从一个移到另一个。 目前,我只知道如何创建多个图并将其绘制在不同的窗口中,如下所示:
在 matplotlib 中绘制小块对象时,由于显示分辨率而引入了伪影。使用抗锯齿并不能解决问题。 这个问题有解决方案吗? import matplotlib.pyplot as plt impo
对于直方图,有一个简单的内置选项 histtype='step' .如何制作相同风格的条形图? 最佳答案 [阅读评论后添加答案] 将可选关键字设置为 fill=False对于条形图: import m
我正在尝试在 (6X3) 网格上创建子图。我对图例的位置有疑问。图例对所有子图都是通用的。 lgend 现在与 y 轴标签重叠 我尝试删除 constrained_layout=True 选项。但这在
我有一个带有一些线段( LineCollection )和一些点的图表。这些线和点有一些与它们相关的值,但没有绘制出来。我希望能够添加鼠标悬停工具提示或其他方法来轻松找到点和线的关联值。这对于点或线段
我想创建一个带有对齐不同曲线文本的图例的图。这是一个最小的工作示例: import matplotlib.pyplot as plt import numpy as np x=np.linspace(
可以说我正在用matplotlib绘制一条线并添加一个图例。 在图例中,其显示为------ Label。当绘制较小的图形尺寸以进行打印时,我发现该行的默认水平长度太长。 是否存在将------ La
我正在使用 matplotlib 构建一个 3D 散点图,但无法使生成的图形具有所有 3 个轴的共同原点。我怎样才能做到这一点? 我的代码(到目前为止),我还没有为轴规范实现任何定义,因为我对 Pyt
我有一个我想使用的绘图布局,其中 9 个不同的数据簇被布置在一个方形网格上。网格中的每个框都包含 3 个并排布置的箱线图。 我最初的想法是这将适合 3x3 子图布局,每个单独的子图本身被划分为 3x1
我的图形从y=-1变为y=10 我想在任意位置写一小段文字,例如x=2000,y=5: ax.annotate('MgII', xy=(2000.0, 5.0), xycoords='data')
我想使用LateX格式来构建一个表达式,其中出现一些数字,但这些数字是用LateX表达式中的变量表示的。 实际的目标是在axes.annotate()方法中使用它,但是为了讨论起见,这里是一个原理代码
我需要比较两组的二维分布。 当我使用 matplotlib.pyplot.contourf并覆盖图,每个等高线图的背景颜色填充整个图空间。有没有办法让每个等高线图的最低等高线级别透明,以便更容易看到每
在R中,有一个locator函数,类似于Matlab的ginput,您可以用鼠标单击图形并选择任何x,y坐标。此外,还有一个名为identify(x,y)的函数,如果您给它绘制了一组绘制的点x,y,然
我想用matplotlib生成矢量图。我尽力了-但输出是光栅图像。这是我使用的: import matplotlib matplotlib.use('Agg') import matplotlib.p
我正在尝试使用 matplotlib 制作具有非常小的灰点的散点图。由于点密度的原因,点需要很小。问题是 scatter() 函数的标记似乎既有线条又有填充。当标记很小时,只有线条可见,而看不到填充,
我不太明白为什么我无法在指定的限制内创建水平和垂直线。我想用这个框绑定(bind)数据。然而,双方似乎并没有遵守我的指示。为什么是这样? # CREATING A BOUNDING BOX # BOT
我是一名优秀的程序员,十分优秀!