需求:
在做樹形可視化圖形時,需要相應的json文件為樹形結(jié)構(gòu)。本例為將所有IP進行一個統(tǒng)計,合并同類項,之后根據(jù)IP的四個字段分為四層。第一層為第一個字段,第二層為第二個字段,以此類推,總共四層。
數(shù)據(jù)格式類似下圖:

image.png
實現(xiàn)思路:
- 1.將IP統(tǒng)計后的結(jié)果以dataframe的數(shù)據(jù)結(jié)構(gòu)存儲;
- 2.定義兩種節(jié)點:
非葉子節(jié)點:
node={"name":"","children":[]}
葉子節(jié)點:
leaf={"name":"","size":0}
- 對所有IP進行一次遍歷,遍歷所有IP的第一個字段,得到不同的第一個字段,并生成一個非葉子節(jié)點。加入列表中。
- 對所有IP進行第二次遍歷,遍歷第二個字段,生成相應的非葉子節(jié)點,并匹配對應的第一個字段,插入到列表中。
- 對所有IP進行第三次遍歷,遍歷第三個字段,生成相應的非葉子節(jié)點,并分別匹配第一個字段和第二個字段,插入到列表中。
- 對所有IP進行第四次遍歷,遍歷第四個字段,生成相應的葉子節(jié)點,并分別匹配第一個字段、第二個字段、第三個字段,插入到列表中。
- 最后做格式的微調(diào),如單引號變?yōu)殡p引號等。
實現(xiàn)代碼:
# -*- 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計數(shù)
srcIpCounts=df[u'firstSeenSrcIp'].value_counts()
srcIpCounts=pd.DataFrame(srcIpCounts)
#定義節(jié)點,node為非葉子節(jié)點,leaf為葉子節(jié)點
node={"name":"","children":[]}
leaf={"name":"","size":0}
result=[]
#第一次遍歷,計算IP的所有第一個數(shù)值的種類并生成Node節(jié)點
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節(jié)點歸到第一次遍歷對應的結(jié)果中
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節(jié)點歸到第二次遍歷對應的結(jié)果中
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節(jié)點歸到上一次遍歷對應的結(jié)果中
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
#拼接成最后的結(jié)果
out={"name":"all","children":'a'}
out["children"]=result
#將里面的單引號改為雙引號
out=str(out)
#print type(out)
out=out.replace("'","\"")
#最后的text文件轉(zhuǎn)換為json即可。
with open('out.txt', 'w') as fout:
fout.write(out)