一、 背景今天准备学习网络图networkx的基本操作。选择的用例为一百年以前美国一些社会科学家从报纸上搜集的“知名女士参加社会活动的记录”,表结构简化如下:
通过网络图能否找出社交中的明星呢?这里说的明星是指:参加社交活动较多且认识其他知名女士较多的Lady。
二、 思路按照以上定义,我们首先探索数据,先找出参加活动较多的女士,结果如下,看起来W01、W03参加活动最多,她们是不是就是我们要找的“明星”呢?
我们还需要找一下,这些人中,谁认识的人较多。这个目标怎么实现呢?老师给我们一个思路:假设参加同一个活动的Lady能相互认识,我们整理一个“女士见面次数表”。这样以来,我们就可以通过活动将这些女士联系起来,并形成一个网络图,形如:
图一
怎么看这样的图,难道在中心位置的就是圈子最大的人吗?为理清这一点,老师提出让我们把见面(同时参加活动)小于4次的信息去掉,再整理出网络图,结果如下:
图二
我们兴奋地发现,网络图上只有两个圈子,这些都是见面次数大于等于4次的人员网络图。
我们再试着降低要求,调小见面次数,让次数变为大于等于3,结果如图三所示:
图三
看上去W3和另一个圈子的W13、W10和W14都有联系,她可以将两个圈子融在一起。同样,W9、W13、W10和W14也起到同样的作用,看来这些就是社交达人了。我们再看看这几个人参加活动的次数:
看上去社交达人W09、W10虽然活动的次数不太多,但却是圈子共融的关键人物之一,大家可以从这个小结论发散思维,考虑一下这两个人有什么样的素质?
三、 Python+networkx脚本实现import matplotlib.pyplotas plt
import pandas as pd
import networkx as nx
data = pd.read_csv(r'D:\southernladies.csv', encoding='GBK')
# 表自身关联,找出和某女士参加相同活动的其他女士
data1 = pd.merge(data, data, left_on='Activity', right_on='Activity')
# 去重
data1 = data1[data1['Lady_x'] < data1['Lady_y']]
# 汇总有关联的女士参加相同活动的次数,以便了解每一对女士的关联密切程度
data1 = data1[['Activity']].groupby([data1['Lady_x'], data1['Lady_y']]).count()
# 将社交活动少于4次的去掉
data1 = data1.drop(index=(data1.loc[data1['Activity'] < 4].index))
# 取出索引的值,生成一个列表,形如[(1,2),(1,3)……]
# 这个索引生成的列表,可以做为网络图的“边”,即指明了边的两个端点
edge = data1.index.tolist()
# 记录权重
weight = data1['Activity'].tolist()
# 得到所有女士节点,以准备网络图的“点”,方法1
# nodes = data.groupby(data['Lady']).count().index.tolist()
'''
# 得到所有女士节点,以准备网络图的“点” 方法2
data1 = data1.reset_index()
nodes1 = data1.drop_duplicates('Lady_x')['Lady_x'].tolist()
nodes2 = data1.drop_duplicates('Lady_y')['Lady_y'].tolist()
nodes = nodes1+nodes2
print(nodes)
g = nx.Graph()
g.add_edges_from(edge)
g.add_nodes_from(nodes)
'''
# 得到所有女士节点,以准备网络图的“点” 方法3:
data1 = data1.reset_index()
g = nx.from_pandas_edgelist(data1, 'Lady_x', 'Lady_y', create_using=nx.Graph())
nx.draw(g, weight=weight, edge_color=weight,
with_labels=True, node_shape='s', alpha=0.9,
node_color='blue', node_size=1000, font_size=14,font_color='yellow')
plt.show()
四、 几处对我个人而言不熟悉的语法整理1、 drop_duplicates()的用法
data1.drop_duplicates('Lady_x')['Lady_x'].tolist()
理解:按()内指定列去重,此后取[ ]内数据转为list
2、 drop的用法
注意格式:drop(index=[行索引]),其中行索引可以用loc[].
3、 groupby多个字段时的用法
注意格式:groupby([f[],f[]]),其中f为dataframe实例名。
4、 重点是networkx画图的方法,先生成一个graph,往graph中添加节点和边后再draw:
g = nx.Graph()
g.add_edges_from(edge)
g.add_nodes_from(nodes)
nx.draw(g)
这个方法不同于pyecharts中的graph的使用方法,如:
graph.add('', nodes, links)pyecharts中的graph是直接往graph中add节点和边即可看到图形,没有最后一个draw的动作。
【语法为自己总结,以便于记忆,非老师所讲,有误之处可以帮助指正,谢谢!】