Python 分析谁才是「权利的游戏」真正的主角?


作者 | 小F
责编 | 伍杏玲
本文经授权转载自法纳斯特(ID:walker398)
上个礼拜权游大结局,最终的结果「布兰」登上了铁王座。
这个结果确实是大家没有想到的。
原本想着如果不是「龙妈」,那么就该是「雪诺」。
怎么就轮到「布兰」了呢。
一个可以随时随地监视别人的人坐上了铁王座,细思极恐...

权游从2011年4月17日开播直到最后一集5月19日,一共历时九年,终于落下了帷幕。
也算是陪伴了一些人的青春,看看上图里的「小布兰」和长大后的「布兰」。
时光荏苒,岁月如梭,有那么点点哈利波特的感觉(同样也是好多年)。
这次找到了一些权游的数据集,针对这些数据来做一些分析。
主要有人物信息,字幕信息以及屏幕时间信息。
这些数据由GitHub上的一位大佬整理的。

杀手榜
数据是JSON文件,都是别人已经整理好的。
如下是人物信息,包含姓名、家族、人物图片、兄弟姐妹等。

这里只看谁干掉的人最多,其余大伙可以自行探索。
读取文件后,进行排序,代码如下:
import?json
#?读取人物信息文件
with?open("characters.json",?'r')?as?load_f:
????load_dict?=?json.load(load_f)
????characters?=?load_dict["characters"]
#?计算人物的杀人数
item?=?{}
for?character?in?characters:
????if?'killed'?in?character.keys():
????????item[character['characterName']]?=?len(character['killed'])
#?排序
top15?=?sorted(item.items(),?key=lambda?x:?x[1],?reverse=True)[:15]
print(top15,?'nn')
#?获取杀手榜前15位,以及是哪位被领盒饭
for?i?in?top15:
????for?character?in?characters:
????????if?character['characterName']?==?i[0]:
????????????print(i[1],?i[0],?character['killed'],?'nn')
结果如下:

看一下前四位狠人,「龙妈」「猎狗」「雪诺」「二丫」。

「猎狗」大叔看似人狠话不多,但是他的内心还是很正义的。

其中「二丫」杀了「夜王」,这一点也没毛病。

就是「雪诺」杀「龙妈」就有点那个啥了,上一秒我们还是“朋友”,下一秒就GG了。

发言榜
下面这个数据是每集的台词,概况如下:

通过遍历字典信息,获取人物发言频次。
import?json
#?读取人物信息文件
with?open("script-bag-of-words.json",?'r',?errors='ignore')?as?load_f:
????load_dict?=?json.load(load_f)
#?对人物人名进行统计
names?=?[]
for?i?in?load_dict:
????for?j?in?i['text']:
????????name?=?j['name']
????????if?name?not?in?names:
????????????names.append(name)
#?print(names)
#?获取人物说话次数
item?=?{}
for?name?in?names:
????num?=?0
????for?i?in?load_dict:
????????for?j?in?i['text']:
????????????if?j['name']?==?name:
????????????????num?+=?1
????item[name]?=?num
#?排序
top15?=?sorted(item.items(),?key=lambda?x:?x[1],?reverse=True)[:15]
for?i?in?top15:
????print(i[1],?i[0])
结果如下:

「小恶魔」「雪诺」「龙妈」「瑟曦」「詹姆」排行前五。
「提利昂」曾经说过“大脑需要书才能变得敏锐,就像剑需要磨刀石一样。”

果然作为读书多的,话也就多了。
不然就只能一句句「俺也一样」了,弑君者「詹姆」,「小恶魔」的哥哥。

虽然前期做了不少坏事,不过最后改邪归正,真的实力圈粉。

出场时间
对场景出现时间进行分析,数据概况如下:

对数据进行处理,代码如下:
import?json
from?datetime?import?datetime
#?读取每集的出场信息
with?open("episodes.json",?'r')?as?load_f:
????load_dict?=?json.load(load_f)
????episodes?=?load_dict["episodes"]
for?episode?in?episodes:
????#?获取每集的片段信息
????for?scene?in?episode["scenes"]:
????????#?处理时间数据
????????start?=?datetime.strptime(scene['sceneStart'],?"%H:%M:%S")
????????end?=?datetime.strptime(scene['sceneEnd'],?"%H:%M:%S")
????????#?国家
????????with?open('got_1.csv',?'a+')?as?f:
????????????f.write(scene['location']?+?','?+?str((end?-?start).seconds)?+?','?+?str(episode["seasonNum"])?+?','?+?str(episode["episodeNum"])?+?'n')
????????#?城市
????????if?'subLocation'?in?scene.keys():
????????????with?open('got_2.csv',?'a+')?as?f:
????????????????f.write(scene['subLocation']?+?','?+?str((end?-?start).seconds)?+?','?+?str(episode["seasonNum"])?+?','?+?str(episode["episodeNum"])?+?'n')
????????#?人物
????????for?people?in?scene['characters']:
????????????with?open('got_3.csv',?'a+')?as?f:
????????????????f.write(people['name']?+?','?+?str((end?-?start).seconds)?+?','?+?str(episode["seasonNum"])?+?','?+?str(episode["episodeNum"])?+?'n')
最后得到三个文件,分别为国家、城市及人物的出现时间。
这里不对每一季进行分析,那样内容太多了,有兴趣的可以自己试试。
import?pandas?as?pd
from?pyecharts?import?Bar
#?读取数据
df?=?pd.read_csv('got_1.csv',?header=None)
#?df?=?pd.read_csv('got_2.csv',?header=None)
#?df?=?pd.read_csv('got_3.csv',?header=None)
#?汇总名称
names?=?[]
for?name?in?df[0]:
????if?name?not?in?names:
????????names.append(name)
item?=?{}
for?name?in?names:
????nums?=?[]
????for?num?in?df[df[0]?==?name][1]:
????????nums.append(num)
????#?列表求和
????s?=?sum(nums)
????#?时间转换
????m,?s?=?divmod(s,?60)
????h,?m?=?divmod(m,?60)
????item[name]?=?"%02d:%02d:%02d"?%?(h,?m,?s)
#?出场时间前15位角色
top15?=?sorted(item.items(),?key=lambda?x:?x[1],?reverse=True)[:15]
for?i?in?top15:
????print(i[1],?i[0])
先看一下区域的时间分布结果:

第一王领,第二北境。
下面是城市的屏幕时间情况。

第一位「君临城」——七大王国的首都。
第二位「临冬城」——史塔克家族的城堡。
最后是人物出现的屏幕时间:

第一位是国王之手「小恶魔」。
第二位是什么都不懂的「雪诺」。
第三位是白手起家最后又被骗的「龙妈」。

对每季的人物进行统计:
#?统计每季人物出场时间
for?i?in?range(1,?9):
????name_1?=?[]
????nums_1?=?[]
????df1?=?df[df[2]?==?i]
????for?j?in?top15:
????????num_1?=?[]
????????for?k?in?df1[df1[0]?==?j[0]][1]:
????????????num_1.append(k)
????????name_1.append(j[0])
????????nums_1.append(sum(num_1))
????print(i,?name_1,?nums_1)
def?people_scenes():
????"""
????每季人物出现时间
????"""
????#?参数数据
????attr?=?['提利昂',?'雪诺',?'龙妈',?'三傻',?'瑟曦',?'二丫',?'詹姆',?'莫尔蒙',?'戴佛斯',?'山姆',?'瓦里斯',?'席恩',?'布蕾妮',?'布兰',?'猎狗']
????v1?=?[4903,?5323,?4900,?3608,?4252,?3655,?2523,?3650,?0,?1918,?2949,?3270,?0,?3115,?2442]
????v2?=?[5257,?2658,?3037,?2455,?3021,?3373,?1363,?1694,?1879,?1225,?1594,?2908,?1869,?1387,?1445]
????v3?=?[4146,?2620,?2760,?2369,?2429,?2612,?2674,?2561,?1636,?2074,?1533,?1605,?2009,?1768,?1283]
????v4?=?[5480,?3818,?2490,?3130,?4694,?2510,?4269,?1634,?1021,?2273,?1332,?1190,?1536,?1427,?2328]
????v5?=?[4469,?5066,?3767,?2919,?3927,?2770,?1889,?2998,?1452,?2742,?876,?1635,?1163,?0,?0]
????v6?=?[2852,?5527,?2473,?3848,?2222,?2294,?2948,?827,?4101,?1268,?1424,?1626,?1749,?2107,?906]
????v7?=?[5849,?7840,?5773,?3436,?3426,?2744,?4074,?4549,?4417,?1747,?3072,?2553,?2313,?1246,?3657]
????v8?=?[8148,?7513,?6494,?3940,?1551,?4357,?3935,?1740,?3679,?2871,?3247,?888,?3817,?3296,?1827]
????#?创建条形图
????bar?=?Bar("权游人物出场时间分布",?title_pos='center',?title_top='18',?width=800,?height=400)
????bar.add("第一季",?attr,?v1,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第二季",?attr,?v2,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第三季",?attr,?v3,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第四季",?attr,?v4,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第五季",?attr,?v5,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第六季",?attr,?v6,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第七季",?attr,?v7,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????bar.add("第八季",?attr,?v8,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=12,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=False,?is_legend_show=True,?label_pos='right',?legend_orient='vertical',?legend_pos='80%',?legend_top='30%',?is_yaxis_inverse=True,?is_splitline_show=False,?is_stack=True)
????#?生成图表
????bar.render("权游人物出场时间分布.html")
people_scenes()
得到结果如下:

最后来看一下第一季的数据:
def?people_season(season,?mes1,?mes2):
????"""
????每季统计
????"""
????attr?=?mes1
????v1?=?mes2
????bar?=?'bar'?+?str(season)
????bar?=?Bar('第'?+?str(season)?+?'季人物出场时间分布',?title_pos='center',?title_top='18',?width=800,?height=400)
????bar.add("",?attr,?v1,?is_convert=True,?xaxis_min=10,?yaxis_label_textsize=8,?is_yaxis_boundarygap=True,?yaxis_interval=0,?is_label_show=True,?is_legend_show=False,?label_pos='right',?is_yaxis_inverse=True,?is_splitline_show=False)
????bar.render('第'?+?str(season)?+?'季人物出场时间分布.html')
#?遍历每一季
for?season?in?range(1,?9):
????df2?=?df[df[2]?==?season]
????for?i?in?df2[0]:
????????if?i?not?in?names:
????????????names.append(i)
????item?=?{}
????#?对人物出现时间进行统计
????for?j?in?names:
????????num_3?=?[]
????????for?k?in?df2[df2[0]?==?j][1]:
????????????num_3.append(k)
????????item[j]?=?sum(num_3)
????#?排序
????top15?=?sorted(item.items(),?key=lambda?x:?x[1],?reverse=True)[:15]
????print(top15)
????name_2?=?[]
????num_2?=?[]
????#?对前15位进行数据汇总
????for?p?in?top15:
????????name_2.append(p[0])
????????num_2.append(p[1])
????print(season,?name_2,?num_2)
????people_season(season,?name_2,?num_2)
结果如下:

有一半都领盒饭了,当然也有坚持到最后的。坚持下来的,狼家的居多。
源码:https://pan.baidu.com/s/1oBYdzs5KtB9TXHWxZ7getg?
提取码:juc9
【END】

作为码一代,想教码二代却无从下手:
听说少儿编程很火,可它有哪些好处呢?
孩子多大开始学习比较好呢?又该如何学习呢?
最新的编程教育政策又有哪些呢?
下面给大家介绍CSDN新成员:极客宝宝(ID:geek_baby)
戳他了解更多↓↓↓

?热 文?推 荐?
?学术界“失守”:IEEE 禁止华为员工参与审稿,学界抗议美政府
?程序员疯狂记事:如何利用众多技术栈构建一个 Web 应用程序?!
?服务迁移之路 | Spring Cloud向Service Mesh转变 | 技术干货
?一文获取36个Python开源项目,平均Star 1667,精选自5000个项目

关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平将发表二〇二六年新年贺词 7904141
- 2 2026年国补政策来了 7808738
- 3 东部战区:开火!开火!全部命中! 7712893
- 4 2026年这些民生政策将惠及百姓 7616985
- 5 小学食堂米线过期2.5小时被罚5万 7519709
- 6 解放军喊话驱离台军 原声曝光 7428214
- 7 为博流量直播踩烈士陵墓?绝不姑息 7327605
- 8 每月最高800元!多地发放养老消费券 7238391
- 9 数字人民币升级 1月1日起将计付利息 7141831
- 10 2026年1月1日起 一批新规将施行 7040675








CSDN
