得到了第二步的两个文件:comment.txt和like.txt
每个文件每一行都是这种格式: A$|$B
而我们想要的好友关系网就是数据结构中的图,我们这里的图采用三元组的思想来存储,即 节点a,节点b,权值
所以我们根据已经得到的两个文件在生成个 relationship.txt
里面存储数据的格式: A$|$B$|$value,这里value就是两者的关系值
那采用算法的思想 :(很重要!!!!)
采用list类型存储:如[ [a, b, value1], [c, d, value2]...... ]
这个命名为relationship,先得到这个数据,最后将这个变量循环写入relationship.txt即可、
得到数据的思想如下:
从comment.txt或者like.txt文件中读一行数据,A $|$ B, 那么遍历relationship,如果A,B没有出现同一个子list中,那么新生成一个子list来记录两者的关系值,如果同时出现在同一个子list,那么改变子list中的关系值,如果是从comment中读的数据那么关系+3,如果是在like中读的文件,那么关系+1
那我们就新建一个文件,创建一个新类
import operator as op
class CalRelationship:
#得到txt文件内容
def get_content(self,txtfile):
file = open(txtfile, encoding='UTF-8')
content = file.read()
file.close()
return content
#开始入口
def start(self):
comments = self.get_content('../comment.txt')
likes = self.get_content('../like.txt')
#开始计算
#评论好友关系+3,点赞好友关系+1
self.cal_relationship_by_data(comments,3)
self.cal_relationship_by_data(likes,1)
if __name__ == '__main__':
# 将关系设置为全局变量以供方便调用
relationships = []
cal = CalRelationship()
cal.start()
#将计算好的关系值写入txt
file = open('relationship.txt', 'w', encoding='UTF-8')
for relationship in relationships:
file.write(relationship[0] + '$|$' + relationship[1] + '$|$' + str(relationship[2]) + '\n')
file.close()
#计算关系值的基础方法
def cal_relationship(self,name1,name2,value):
global relationships
# 设置两个好友同时是否存在于三元组的标志
flag = False
for relationship in relationships:
# 如果两个人都在那么改变其关系值,并改变标记值
if name1 in relationship and name2 in relationship:
#存储关系图在三元组 [ [name1,name2,value], [name3,name4,vaule]....]
relationship[2] += value
flag = True
# 如果两好友中一者或都不在三元组内,那么添加
if flag == False and op.eq(name1, name2) == False:
# 第一次进去就有个初值
relationships.append([name1, name2, value])
然后就
#通过评论和点赞计算关系值
def cal_relationship_by_data(self,datas,value):
count = 0
data_list = datas.split('\n')
for element in data_list:
count += 1
data = element.split('$|$')
#最后一个是空
if data[0] == '':
return 0
self.cal_relationship(data[0],data[1],value)
print('已经分析了 '+ str(count)+' 行数据')
现在已经完成绝大部分了,得到的relationship.txt就像这样子
这里良心一个数据可视化前端框架 : echarts
使用里面的力引导向图,http://echarts.baidu.com/examples/editor.html?c=graph-force
关于这个的基础使用可以看:echarts3.0之关系图详解
因为要在浏览器打开html界面,需要把数据写入html文件
所以首选用php啊,在html内就可以直接解释岂不美滋滋
在html的script标签下改变node和link即可
刚开始想的是直接读一遍数据然后生成节点的同时动态生成边,尝试了好久,但都没成功,后来一想干嘛要把事情复杂化,可以先读一遍数据先生成全部节点,然后再读一遍数据生成边,果然这样分开就简单多了
关键代码如下
"nodes": [
$value) {
#存在则不生成
if($data[0] == $key )
$flag_0 = false;
if($data[1] == $key )
$flag_1 = false;
}
//因为存在自己给自己点赞或者评论的情况,那么关系表里会出现自己和自己的关系值,但只需要一个节点就够了,这里有个巨大无比的坑看下面解释
if($data[0] == $data[1])
$flag_1=false;
if($flag_0){
$name_id["$data[0]"] = $id;
$id++;
}
if($flag_1){
$name_id["$data[1]"] = $id;
$id++;
}
}
#根据name_id生成全部节点
foreach ($name_id as $key => $value) {
?>
{ "id": "", "category": 0, "name": ""},
],//数据内容
//接收格式均为json对象数组
"links": [
{
"source": ,//起始节点,0表示第一个节点
"target": , //目标节点,1表示与索引为1的节点进行连接
"lineStyle": {"width":}
},
]//关系对应
这里有个点需要特别注意的!!!就是生成节点的id必须连续!!!必须连续!!!!不然下面的link的target和source的id就算和节点的id对应上了,但是实际出来的图连接的却不是target的id值,这个大概花了三四个人小时才发现这个问题,爬出来这个给自己挖的巨坑
而会使得id值不连续的原因:会出现自己给自己点赞评论的情况,然后关系文件里就会有 A $|$ A,这时候必须加上判断,两个名字一样时只生成一个节点,不然会生成两个节点,而这个工具不允许节点的name一样,这样后面生成的id会把前面的id覆盖,前面的那个id就没了
得到最后的图啦