需求:
在做树形可视化图形时,需要相应的json文件为树形结构。本例为将所有IP进行一个统计,合并同类项,之后根据IP的四个字段分为四层。第一层为第一个字段,第二层为第二个字段,以此类推,总共四层。
数据格式类似下图:
image.png
实现思路:
- 1.将IP统计后的结果以dataframe的数据结构存储;
- 2.定义两种节点:
非叶子节点:
node={"name":"","children":[]}
叶子节点:
leaf={"name":"","size":0}
- 对所有IP进行一次遍历,遍历所有IP的第一个字段,得到不同的第一个字段,并生成一个非叶子节点。加入列表中。
- 对所有IP进行第二次遍历,遍历第二个字段,生成相应的非叶子节点,并匹配对应的第一个字段,插入到列表中。
- 对所有IP进行第三次遍历,遍历第三个字段,生成相应的非叶子节点,并分别匹配第一个字段和第二个字段,插入到列表中。
- 对所有IP进行第四次遍历,遍历第四个字段,生成相应的叶子节点,并分别匹配第一个字段、第二个字段、第三个字段,插入到列表中。
- 最后做格式的微调,如单引号变为双引号等。
实现代码:
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 29 15:06:39 2017
@author: gly
"""
import pandas as pd
df=pd.read_csv('output.csv')
#源IP计数
srcIpCounts=df[u'firstSeenSrcIp'].value_counts()
srcIpCounts=pd.DataFrame(srcIpCounts)
#定义节点,node为非叶子节点,leaf为叶子节点
node={"name":"","children":[]}
leaf={"name":"","size":0}
result=[]
#第一次遍历,计算IP的所有第一个数值的种类并生成Node节点
ip1Num=[]
for index,row in srcIpCounts.iterrows():
name=index.split(".")[0]
if name not in ip1Num:
ip1Num.append(name)
node={"name":name,"children":[]}
result.append(node)
#第二次遍历,计算IP前两位的不同种类并生成Node节点归到第一次遍历对应的结果中
ip2Num=[]
for index,row in srcIpCounts.iterrows():
name1=index.split(".")[0]
name2='.'.join(index.split(".")[0:2])
if name2 not in ip2Num:
ip2Num.append(name2)
node={"name":name2,"children":[]}
for i in result:
if i["name"]==name1:
i["children"].append(node)
break
#第三次遍历,计算IP前三位的不同种类并生成Node节点归到第二次遍历对应的结果中
ip3Num=[]
for index,row in srcIpCounts.iterrows():
name1=index.split(".")[0]
name2='.'.join(index.split(".")[0:2])
name3='.'.join(index.split(".")[0:3])
if name3 not in ip3Num:
ip3Num.append(name3)
node={"name":name3,"children":[]}
for i in result:
if i["name"]==name1:
for j in i["children"]:
if j["name"]==name2:
j["children"].append(node)
break
#第四次遍历,计算IP所有位的不同种类并生成leaf节点归到上一次遍历对应的结果中
for index,row in srcIpCounts.iterrows():
name1=index.split(".")[0]
name2='.'.join(index.split(".")[0:2])
name3='.'.join(index.split(".")[0:3])
name4='.'.join(index.split(".")[0:4])
leaf={"name":name4,"size":row.values[0]}
for i in result:
if i["name"]==name1:
for j in i["children"]:
if j["name"]==name2:
for k in j["children"]:
if k["name"]==name3:
k["children"].append(leaf)
break
#拼接成最后的结果
out={"name":"all","children":'a'}
out["children"]=result
#将里面的单引号改为双引号
out=str(out)
#print type(out)
out=out.replace("'","\"")
#最后的text文件转换为json即可。
with open('out.txt', 'w') as fout:
fout.write(out)
网友评论