乐趣区

Python-分析谁才是权力的游戏第八季真正的C位

上个礼拜《权力的游戏第八季》放出大结局,最终的结果「布兰」登上了铁王座。

这个结果确实是大家没有想到的。

原本想着如果不是「龙妈」,那么就该是「雪诺」。

怎么就轮到「布兰」了呢。

一个可以随时随地监视别人的人坐上了铁王座,细思极恐 …

《权力的游戏》系列从 2011 年 4 月 17 日开播直到最后一集 5 月 19 日,一共历时九年,终于落下了帷幕。

也算是陪伴了一些人的青春,看看上图里的「小布兰」和长大后的「布兰」。

时光荏苒,岁月如梭,有那么点点哈利波特的感觉(同样也是好多年)。

这次找到了一些权游的数据集,针对这些数据来做一些分析。

主要有人物信息,字幕信息以及屏幕时间信息。

这些数据由 GitHub 上的一位大佬整理的。

杀手榜

数据是 JSON 文件,都是别人已经整理好的。

如下是人物信息,包含姓名、家族、人物图片、兄弟姐妹等。

这里只看谁干掉的人最多,其余大伙可以自行探索。

读取文件后,进行排序,代码如下:

importjson

读取人物信息文件

withopen(“characters.json”,’r’)asload_f:

load_dict = json.load(load_f)

characters = load_dict[“characters”]

计算人物的杀人数

item = {}

forcharacterincharacters:

if’killed’incharacter.keys():

item[character[‘characterName’]] = len(character[‘killed’])

排序

top15 = sorted(item.items(), key=lambdax: x[1], reverse=True)[:15]

print(top15,’nn’)

获取杀手榜前 15 位, 以及是哪位被领盒饭

foriintop15:

forcharacterincharacters:

ifcharacter[‘characterName’] == i[]:

print(i[1], i[], character[‘killed’],’nn’)

结果如下:

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

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

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

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

发言榜

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

通过遍历字典信息,获取人物发言频次。

importjson

读取人物信息文件

withopen(“script-bag-of-words.json”,’r’, errors=’ignore’)asload_f:

load_dict = json.load(load_f)

对人物人名进行统计

names = []

foriinload_dict:

forjini[‘text’]:

name = j[‘name’]

ifnamenotinnames:

names.append(name)

print(names)

获取人物说话次数

item = {}

fornameinnames:

num =

foriinload_dict:

forjini[‘text’]:

ifj[‘name’] == name:

num +=1

item[name] = num

排序

top15 = sorted(item.items(), key=lambdax: x[1], reverse=True)[:15]

foriintop15:

print(i[1], i[])

结果如下:

「小恶魔」「雪诺」「龙妈」「瑟曦」「詹姆」排行前五。

「提利昂」曾经说过“大脑需要书才能变得敏锐,就像剑需要磨刀石一样。”

果然作为读书多的,话也就多了。

不然就只能一句句「俺也一样」了,弑君者「詹姆」,「小恶魔」的哥哥。

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

出场时间

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

对数据进行处理,代码如下:

importjson

fromdatetimeimportdatetime

读取每集的出场信息

withopen(“episodes.json”,’r’)asload_f:

load_dict = json.load(load_f)

episodes = load_dict[“episodes”]

forepisodeinepisodes:

获取每集的片段信息

forsceneinepisode[“scenes”]:

处理时间数据

start = datetime.strptime(scene[‘sceneStart’],”%H:%M:%S”)

end = datetime.strptime(scene[‘sceneEnd’],”%H:%M:%S”)

国家

withopen(‘got_1.csv’,’a+’)asf:

f.write(scene[‘location’] +’,’+ str((end – start).seconds) +’,’+ str(episode[“seasonNum”]) +’,’+ str(episode[“episodeNum”]) +’n’)

城市

if’subLocation’inscene.keys():

withopen(‘got_2.csv’,’a+’)asf:

f.write(scene[‘subLocation’] +’,’+ str((end – start).seconds) +’,’+ str(episode[“seasonNum”]) +’,’+ str(episode[“episodeNum”]) +’n’)

人物

forpeopleinscene[‘characters’]:

withopen(‘got_3.csv’,’a+’)asf:

f.write(people[‘name’] +’,’+ str((end – start).seconds) +’,’+ str(episode[“seasonNum”]) +’,’+ str(episode[“episodeNum”]) +’n’)

最后得到三个文件,分别为国家、城市及人物的出现时间。

这里不对每一季进行分析,那样内容太多了,有兴趣的可以自己试试。

importpandasaspd

frompyechartsimportBar

读取数据

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 = []

fornameindf[]:

ifnamenotinnames:

names.append(name)

item = {}

fornameinnames:

nums = []

fornumindf[df[] == 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=lambdax: x[1], reverse=True)[:15]

foriintop15:

print(i[1], i[])

先看一下区域的时间分布结果:

第一王领,第二北境。

下面是城市的屏幕时间情况。

第一位「君临城」——七大王国的首都。

第二位「临冬城」——史塔克家族的城堡。

最后是人物出现的屏幕时间:

第一位是国王之手「小恶魔」。

第二位是什么都不懂的「雪诺」。

第三位是白手起家最后又被骗的「龙妈」。

对每季的人物进行统计:

统计每季人物出场时间

foriinrange(1,9):

name_1 = []

nums_1 = []

df1 = df[df[2] == i]

forjintop15:

num_1 = []

forkindf1[df1[] == j[]][1]:

num_1.append(k)

name_1.append(j[])

nums_1.append(sum(num_1))

print(i, name_1, nums_1)

defpeople_scenes():

“””

每季人物出现时间

“””

参数数据

attr = [‘ 提利昂 ’,’ 雪诺 ’,’ 龙妈 ’,’ 三傻 ’,’ 瑟曦 ’,’ 二丫 ’,’ 詹姆 ’,’ 莫尔蒙 ’,’ 戴佛斯 ’,’ 山姆 ’,’ 瓦里斯 ’,’ 席恩 ’,’ 布蕾妮 ’,’ 布兰 ’,’ 猎狗 ’]

v1 = [4903,5323,4900,3608,4252,3655,2523,3650,,1918,2949,3270,,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,,]

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=, 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=, 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=, 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=, 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=, 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=, 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=, 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=, 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()

得到结果如下:

最后来看一下第一季的数据:

defpeople_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=, is_label_show=True, is_legend_show=False, label_pos=’right’, is_yaxis_inverse=True, is_splitline_show=False)

bar.render(‘ 第 ’+ str(season) +’ 季人物出场时间分布.html’)

遍历每一季

forseasoninrange(1,9):

df2 = df[df[2] == season]

foriindf2[]:

ifinotinnames:

names.append(i)

item = {}

对人物出现时间进行统计

forjinnames:

num_3 = []

forkindf2[df2[] == j][1]:

num_3.append(k)

item[j] = sum(num_3)

排序

top15 = sorted(item.items(), key=lambdax: x[1], reverse=True)[:15]

print(top15)

name_2 = []

num_2 = []

对前 15 位进行数据汇总

forpintop15:

name_2.append(p[])

num_2.append(p[1])

print(season, name_2, num_2)

people_season(season, name_2, num_2)

结果如下:

有一半都领盒饭了,当然也有坚持到最后的。坚持下来的,狼家的居多。

退出移动版