最近在研究关系网络,需要构造程度中心度、中介中心度等多个变量。虽众多论文都给出了大致相同的构造方法,但是按照这些方法照葫芦画瓢还是比较难。现有的数据库CNRDS只有独立董事的数据,和我关注的不太一样因此只能自行构建数据。陈运森(2011)给出的构造方法很详细,但是需要用到Pajek,本人之前没有接触过社会网络分析,粗浅的学习了一下发现最重要的就是构建“高管ID-高管ID”.net的这个数据。本以为利用CSMAR的数据+Python可以很快构建出来,但是无奈数据量太大,运行时间过长,且容易出现内存泄露的情况。在几经探索之下,终于找到了一个可以在较低时间成本可复现(自行构建)的方法,因此分享出来,如有兴趣可交流优化方法:
[数据准备] CSMAR高管数据,至少包括证券代码,统计截止日期,人物ID
[运行环境] 主要瓶颈是内存,我的设备是16g内存
[具体过程]
1、 数据准备
CSMAR上下载的原始文件,利用pandas读入数据,以【统计日期、人员ID】为关键词进行分组,提取组内出现的所有证券代码,然后反向查询在这些公司任职的人员ID,构建出如下共线矩阵。(用时13小时,暂时没想出优化方案)
2、 长数据转化为宽数据在将数据构建“高管-高管”矩阵前,我先将其转化为了宽数据。按年份进行遍历,对于每年的数据,进行如下相同的操作。使用[co-occurrence].str.split(‘;’,expand=True)进行分列,构建出如下矩阵。可以看出每行中的ID,就是共现的ID,我们将这个数据标注为df。
其中由于共现的人数不一样,因此有些行的后面一些列是空的,这个问题在第三步解决。
3、 转化为“高管-高管”矩阵
对df进行转置为df_t,建立列名循环,通过df_t[某列列名].values (这种方法最快)获取每列的所有数据,在删除空缺值之后利用itertools包内的combinations方法求出每一列的所有组合。得到所有组合后去重,保存为nkl格式的文件。(请勿保存为excel,可能会超过最大长度)。运行25分钟。
其实在这一步,很多人会产生不一样的想法,比如说不进行转置,通过iterrows/apply的方法进行遍历来求解,但是这样的速度很慢。(可能会慢上数百-数千倍之间,可参考,英文原文为HowTo Make Your Pandas Loop 71803 Times Faster | by Benedikt Droste | Towards DataScience、打不开可以看如何让你的pandas循环更快 - 简书 (jianshu.com))
4、 转化为net文件
将生成数据依次读为dataframe格式,然后利用pajek-tools包,pkl文件转化为net文件。我下载的源码在运行时会报错:to_csv() got an unexpected keyword argument‘line_terminator’;应该是开发者版本不一样,请将line_terminator更改为lineterminator即可正常运行(6分钟)
5、 利用自己擅长的方法进行网络分析
我之后使用Pajek进行分析(但是还是速度慢,所以我继续用了py),但是大同小异,请根据自己的情况进行工具选用
6、 计算网络中心度等一系列指标
在得到每年每个高管的网络中心度指标后,通过高管ID和企业代码Match,由此计算相应的指标