硬核!宝可梦八大世代数据大揭秘
目标:利用Python对宝可梦八大世代做数据分析
一、各系数量分析
二、各世代宝可梦数量分析
三、种族值分析
四、传说宝可梦分析
五、各世代推荐宝可梦
六、特性分析:特性种类、隐藏特性种类、占比(待更新)
零、预备工作&指标解释 #导入三个Python常用数据分析的库 import numpy as np import pandas as pd #画图包导入 import matplotlib.pyplot as plt plt.style.use(style="ggplot") #import missingno as msno import seaborn as sns sns.set() #设置画图空间为 Seaborn 默认风格 #将文件读取进来 pokemon = pd.read_excel("/Users/glenji/Desktop/pokemon (1).xlsx")
#指标解释 #abilities-1特性1,abilities-2特性2,abilities-x特性x #classfication宝可梦分类、classfication-CN宝可梦中文分类 #type1属性1,type2属性2 #attack攻击 #defense防御 #hp血量 #sp_attack特攻 #sp_defense特防 #speed速度 #base_total种族值总数
一、各系数量分析
总结:以下分析仅为单系,双系的分析暂无。
各系中,水系、一般系、草系三个的数量比较多,其中水系占比13.56%,一般系占比12.02%,草系占比9.48%;
各系中,飞行系占比最少,仅0.37%(唯一一个低于1%的);
①各系的数量:先做个简单的计数统计,可以初步看到水系、一般系、草系三个的数量比较多。水系那么多,可能因为日本靠海,他们比较喜欢吃鱼吧哈哈哈。 #查看各系的数量 out = pokemon[["type1","is_legendary"]].groupby("type1").count() print(out)
②绘制一个柱形图来看看效果: #柱形图查看各世代宝可梦不同种族数量 pokemon["type1-EN"].value_counts().plot.bar()
③绘制饼图看看效果:水系、一般系、草系为数量前三位,冰系、妖精系、飞行系为数量后三位,有点出乎意料,飞行系竟然是最少的,仅0.37%(唯一一个低于1%的)。水系占比13.56%,一般系占比12.02%,草系占比9.48%。 #查看各系的占比 #水系是最多的,为什么呢,可能是因为日本人靠海喜欢吃鱼吧哈哈哈 fig,ax = plt.subplots(2,1,figsize=(15,10)) pokemon["type1-EN"].value_counts().plot.pie(ax=ax[0],shadow=False,autopct="%1.2f%%") ax[0].set_ylabel("") #设置y轴标签 ax[0].set_xlabel("type1-EN") #设置x轴标签 sns.countplot("type1-EN",data=pokemon,ax=ax[1]) ax[1].set_ylabel("") ax[1].set_xlabel("type1-EN") plt.show()
二、各世代宝可梦分析
总结:
第5世代是宝可梦数量最多的世代有156只,第6世代是宝可梦数量最少的世代,仅72只;
①先做个简单的计数统计(value_counts),可以看到第5世代是宝可梦数量最多的世代有156只,第一世代次之(第一世代的151手办现在已经很贵很贵很贵了);第6世代是宝可梦数量最少的世代,才72只。 #计算一下各世代的宝可梦数量 pokemon["generation"].value_counts()
②再画个柱形图看看效果: #柱形图查看各世代宝可梦数量 pokemon["generation"].value_counts().plot.bar()
三、种族值解析
总结:
种族值6大属性中,血量hp的异常值较多;
整体种族值呈双峰分布,以300和500左右的分布较多;
龙系的种族值均值高达515,是最值得培育的种族,其次是钢系、超能力系;而虫系是最可怜的种族,平均种族值仅有378,草系、一般系也惨兮兮;
种族值均值为439,中位数是440,培育宝可梦如果在乎强度,那应该选择高于这两值的宝可梦,如果是真爱党的话,则无所谓了;
①绘制线箱图查看各种族值的大致情况:可以看到hp即血量的异常值较多。 #绘制线箱图 #可以看到hp的异常值较多 plt.figure(figsize=(10,5)) #设置画布大小 sns.boxplot(data=pokemon[["hp","attack","defense","sp_attack","sp_defense","speed"]])
②查看种族值的分布图:有点类似双峰分布,最多种族值分布在300和500附近。之前世代种族值最高的是800左右,第八世代出了个无极汰那极巨化一下子将种族值上限提高到1000以上。 #种族值分布 plt.hist(pokemon["base_total"],bins=35) plt.xlabel("total_stats") plt.ylabel("Frequency")
③通过小提琴图观察各个种族的种族值特性:可以看到龙系的整体种族值是相对较高的。 #psychic超能力 #bug虫系 #fairy妖精系 #通过小提琴的厚度显示的分布 sns.set_style("whitegrid") #小提琴图 plt.figure(figsize=(15,5)) #设置画布大小 sns.violinplot(x="type1-EN",y="base_total",data=pokemon)
④通过数据透视表,了解完整的各种族的平均种族值情况,得出什么种族是最值得培育的:得到的结论是龙系的种族值均值高达515,是最值得培育的种族,其次是钢系、超能力系;而虫系是最可怜的种族,平均种族值仅有378,草系、一般系也惨兮兮。 #建立数据透视表 #计算一下各系宝可梦种族值分布 #新建一个数据表格,用于保存世代generation与是否传说is_legendary两列数据 pokemon2=pokemon[["type1","base_total"]] pokemon_z=pokemon2.pivot_table(values="base_total", #计算的值 index="type1", #透视的行,分组的依据 aggfunc="mean") #聚合函数 # 对透视表进行降序排列 pokemon_z = pokemon_z.sort_values(by="base_total", # 排序依据 ascending=False # 是否升序排列 ) pokemon_z
⑤再看看各系种族值的描述型数据统计:种族值均值为439,中位数是440,各位小伙伴,低于这俩值的宝可梦你要是培育的话,那就真的是真爱了。 #各系种族值得描述性数据情况 pokemon_z.describe()
⑥推荐一些培育性价比比较高的宝可梦:种族值高于570,但非传说宝可梦的准神。 #找到非传说宝可梦但是种族值非常优秀,值得培育的宝可梦 pokemon[(pokemon["base_total"] >= 570) & (pokemon.is_legendary == 0)]["chinese_name"].head(100)
⑦还可以绘制一些种族值之间的关系图:可以看到attack和defense基本呈正相关,其他的你也可以再试试。 #查看HP和Attack的相关性 import scipy.stats as stats from warnings import filterwarnings filterwarnings("ignore") sns.jointplot(x="defense",y="attack",data=pokemon).annotate(stats.pearsonr) plt.show()
四、传说宝可梦分析
总结:
传说宝可梦最多的是第7世代,一共有25只,占比28%;最少的是第1世代,只有5只,占比3%;
越往后的世代传说宝可梦倾向于越多;
特攻值与是否为传说宝可梦相关度最高,而防御与是否为传说宝可梦的相关度最低;
传说宝可梦的种族值平均高达611,而非传说宝可梦的种族值平均为410;
种族与是否为传说宝可梦没有很强的相关性,相对来说超能力系psychic、龙系dragon是传说宝可梦的概率较高;
①通过数据透视表统计一下各世代传说宝可梦数量:可以看到传说宝可梦最多的是第7世代,一共有25只;最少的是第1世代,只有5只;有个比较明显的趋势是越往后的世代传说宝可梦倾向于越多。 #新建一个数据表格,用于保存世代generation与是否传说is_legendary两列数据 pokemon1=pokemon[["generation","is_legendary"]] #建立数据透视表 pokemon_p=pokemon1.pivot_table(values="is_legendary", #计算的值 index="generation", #透视的行,分组的依据 aggfunc="sum") #聚合函数 pokemon_p
②对数据透视表进行数值降序排列:可以更明显的看清楚各世代传说宝可梦的数量排列。 # 对透视表进行降序排列 pokemon_p = pokemon_p.sort_values(by="is_legendary", # 排序依据 ascending=False # 是否升序排列 ) pokemon_p
③对新的透视结果做折线图展示: #对新的透视结果做折线图展示 x=[1,2,3,4,5,6,7,8] y=pokemon_p["is_legendary"] plt.plot(x,y) plt.show()
④各世代宝可梦数量及传说宝可梦对比图: #查看各世代宝可梦数量 f,ax=plt.subplots(1,2,figsize=(18,5)) #新建画布 pokemon["generation"].value_counts().plot.bar(ax=ax[0]) #绘制世代宝可梦数量柱形图 ax[0].set_ylabel("countS") #设置y轴标签 ax[0].set_title("Generation") #设置x轴标签 sns.countplot("generation",hue="is_legendary",data=pokemon,ax=ax[1]) #绘制世代传说宝可梦数量对比柱形图 ax[1].set_title("Legendary VS Generation") #设置标题 plt.show()
⑤计算各世代传说宝可梦占比:通过数据透视表操作。 #计算一下各世代传说宝可梦数量 #新建一个数据表格,用于保存世代generation与是否传说is_legendary两列数据 pokemon1=pokemon[["generation","is_legendary","pokedex_number"]] #建立数据透视表 pokemon_p=pokemon1.pivot_table(values="is_legendary", #计算的值 index="generation", #透视的行,分组的依据 aggfunc="sum") #聚合函数 pokemon_q=pokemon1.pivot_table(values="pokedex_number", #计算的值 index="generation", #透视的行,分组的依据 aggfunc="count") #聚合函数 pokemon_w = pd.concat([pokemon_p,pokemon_q],axis=1) #用concat将两个表格连在一起 pokemon_w
可以看到第7世代的传说宝可梦占比最高,达到28%;而第1世代是最低的,只有3%。 #计算一下各世代传说宝可梦占比 pokemon_c = pokemon_w["is_legendary"]/pokemon_w["pokedex_number"] pokemon_c
⑥查看6大能力值与是否传说、世代的相关关系:先用相关关系矩阵查看效果。 #查看六大能力值与是否传说、世代的相关关系 pokemonNew = pokemon[["hp","attack","defense","sp_attack","sp_defense","speed","generation","is_legendary"]] pokemonNewCorr=pokemonNew.corr() plt.figure(figsize=(10,10)) #设置画布 sns.heatmap(pokemonNewCorr,annot=True,cmap="RdGy") plt.show()
查看各个能力值与是否为传说宝可梦的相关性排序:得到的结论是特攻值与是否为传说宝可梦相关度最高,也就是说传说宝可梦的特攻属性值一般是较高的。而防御与是否为传说宝可梦的相关度最低。 #查看各个特征与是否为传说宝可梦的相关性排序 pokemonNewCorr["is_legendary"].sort_values(ascending=False)
⑦传说宝可梦的平均种族值:传说宝可梦的种族值平均高达611,而非传说宝可梦的种族值平均为410。 pokemonchuanshuo = pokemon[["base_total","is_legendary"]] #先将种族值和是否传说两列数据取出 pokemonchuanshuo1=pokemonchuanshuo.pivot_table(values="base_total", #计算的值 index="is_legendary", #透视的行,分组的依据 aggfunc="mean") #聚合函数 # 对透视表进行降序排列 pokemonchuanshuo1 = pokemonchuanshuo1.sort_values(by="base_total", # 排序依据 ascending=False # 是否升序排列 ) pokemonchuanshuo1
⑧分析不同种族与传说宝可梦的相关关系:得出的结论是种族与是否为传说宝可梦没有很强的相关性,相对来说超能力系、龙系是传说宝可梦的概率较高。 #将种族type1做转码 type1Df = pd.DataFrame() #存放提取后的特征 type1Df = pd.get_dummies(pokemon["type1"],prefix="type1") #使用get_dummies进行one-hot编码,列名前缀是Embarked type1Df.head(10)
#将转码后的数据连接到原来的数据表格 pokemon = pd.concat([pokemon,type1Df],axis=1) #添加one-hot编码产生的虚拟变量(dummy variable)到pokemon中 pokemon.head()
#查看不同种族与是否传说、世代的相关关系 pokemonNew = pokemon[ ["type1_Bug", "type1_Dark", "type1_Dragon", "type1_Electric", "type1_Fairy", "type1_Fighting", "type1_Fire", "type1_Flying", "type1_Ghost", "type1_Grass", "type1_Ground", "type1_Ice", "type1_Normal", "type1_Poison", "type1_Psychic", "type1_Rock", "type1_Steel", "type1_Water", "generation", "is_legendary"] ] pokemonNewCorr1=pokemonNew.corr() plt.figure(figsize=(20,20)) #设置画布 sns.heatmap(pokemonNewCorr1,annot=True,cmap="Blues") plt.show()
#查看各个种族与是否为传说宝可梦的相关性排序 pokemonNewCorr1["is_legendary"].sort_values(ascending=False)
五、各世代推荐宝可梦 # 能力测评 属性值加起来×base_total def ability_value(x, output_number): pokemon = x.copy() pokemon = pokemon[pokemon.is_legendary == 0] #因为是平民策略,把神兽都排除掉 Xlist = [] # Xlist 是所有feature name,也就是宝可梦的所有属性名 for line in pokemon: row = line.strip().split(",") Xlist.append(row) against_data = pokemon[Xlist[1]] Xlist = np.array(Xlist) for i in range(2, 18): # against_data 为所有的against_??权值加起来的总和,和战斗力成正相关 against_data = against_data + np.array(pokemon[Xlist[i]]) base_total_value = pokemon["base_total"] battle_value = against_data.mul(base_total_value, axis=0) rank_value = battle_value.sort_values(by=["against_bug"], ascending=False, na_position="first") rank_number = rank_value.axes[0].tolist() for i in range(0, output_number): print("【name】: ", pokemon.chinese_name[rank_number[i]], " 【base total】: ", pokemon.base_total[rank_number[i]]) return 0
def type_prefer(x): pokemon = x.copy() type_total = pokemon.type1.drop_duplicates(keep="first") type_total.reset_index(drop=True, inplace=True) for typenum in range(0, len(type_total)): each_type_pokemon1 = pokemon.loc[pokemon["type1"] == type_total[typenum]] each_type_pokemon2 = pokemon.loc[pokemon["type2"] == type_total[typenum]] each_type_pokemon = each_type_pokemon1.append(each_type_pokemon2) print("type name: ", type_total[typenum]) ability_value(each_type_pokemon, 3) # 每种属性输出最牛逼的3个 print("------------------")
# 从培养难度考虑,培养经验值除以捕捉率,再乘以能力值,全部标准化 def training_hard_level(x, output_number): pokemon = x.copy() pokemon = pokemon[pokemon.is_legendary == 0] # 因为是平民策略,把神兽都排除掉 # monitor的捕捉率按255算,因为反正能力值都一样,算好抓的 pokemon.capture_rate[773] = 255 pokemon.capture_rate = pd.to_numeric(pokemon.capture_rate) normalization_base_total = (pokemon.base_total - pokemon.base_total.min()) / ( pokemon.base_total.max() - pokemon.base_total.min()) normalization_capture_rate = (pokemon.capture_rate - pokemon.capture_rate.min()) / ( pokemon.capture_rate.max() - pokemon.capture_rate.min()) normalization_experience_growth = (pokemon.experience_growth - pokemon.experience_growth.min()) / ( pokemon.experience_growth.max() - pokemon.experience_growth.min()) Difficulty_level = normalization_experience_growth / normalization_capture_rate * normalization_base_total Difficulty_level = Difficulty_level.sort_values(ascending=False, na_position="first") rank_number = Difficulty_level.axes[0].tolist() for i in range(0, output_number): print("【name】: ", pokemon.chinese_name[rank_number[i]], " 【base total】: ", pokemon.base_total[rank_number[i]]) return 0
if __name__ == "__main__": pokemon_Data = pd.read_excel("/Users/glenji/Desktop/pokemon.xlsx") # 首先要确定是哪一代的游戏 1-7代 Xlist = [] for line in pokemon_Data: row = line.strip().split(",") Xlist.append(row) generation_1 = pokemon_Data.iloc[0:151] generation_2 = pokemon_Data.iloc[0:251] generation_3 = pokemon_Data.iloc[0:386] generation_4 = pokemon_Data.iloc[0:493] generation_5 = pokemon_Data.iloc[0:649] generation_6 = pokemon_Data.iloc[0:721] generation_7 = pokemon_Data.iloc[0:801] print("以第2代为例:") print("===============纯从能力值考虑,前十名的宝可梦有:==================") ability_value(generation_2,10) print("==============考虑捕捉+训练难度,前十名的宝可梦有:===============") training_hard_level(generation_2, 10) print("============考虑属性多样爱好者,每个属性的前三甲宝可梦有:===========") type_prefer(generation_3)
最美冬日旅游目的地清单出炉,你去过几个?冬天的来临也暗示着今年即将过去今年你们心愿都实现了吗想去的地方都去过几个?还未实现旅行计划的别错过这些冬日旅行地长白山冬日的长白山宛如冰雪童话世界,有着媲美阿尔卑斯山地区的粉雪,是
绝了!湖人4换1交易有望达成,三巨头联手博扬,还要签安东尼湖人终于回到了正轨,在2胜10负开局后,湖人最近10场比赛取得了8胜2负,其中战胜雄鹿的比赛含金量十足。雄鹿排名东部第二,是真正的争冠球队。湖人能够客场击败东部第二,证明他们是真有
梅西球王80后,每天1针,6年2190针,战胜坎坷非你想象1987年,阿根廷圣菲省罗萨里奥的一个工人家庭里,一个男孩出生了,这个男孩就是梅西。球场上的梅西,双目放光一球王家谱,祖上都是外国人梅西的父母都是工厂的工人,为了生活得更好一点,这
委以重任,王楠承担乒协新岗位,辅佐刘国梁,助力国乒前进虽然退役之后的王楠并没有走上乒乓球管理的岗位,但是刘国梁真的应该庆幸国乒有这样的大师姐。论功行赏,在国乒获得奥运会冠军的时候,王楠是大手一挥,毫不犹豫的拿出价值3500万的豪宅奖励
一封情书,祝你生日快乐,俞尘今日情感文亲爱的俞尘展信佳。从初识至今,已有423天。我曾将自己归于异类。我写我是翻山越岭,最终拂衣远去,自愿独自来到孤岛,却又疯狂想与外界联系的旅人。是无法忍受孤独,将自己燃尽,
信任相信一个人作者李纪春信任相信一个人作者李纪春信任,是人与人沟通的必要条件人生之幸,莫过于被人信任人生之憾,莫过于失信别人我们去信任他,他却失了信,那么,以后就不会有什么人去相信他了,甚至可以说,就是一
天际的世界在浩瀚的天际世界之中,阳光是万物的主宰,在天体就是太阳,睡觉醒来就是一天,睡觉不醒就是一世,睡觉多好,没有记忆,没有烦忧,所以把一呼一吸当作一年。那才是天际的世界。人从呱呱的一声诞
四十不惑年近四十而不惑的年龄,方觉人生才是自己的人生,方觉是在走自己的路,方觉是在为自己而活!有多少跟我一样,快年近四十的姐妹们,你们是否曾经也迷茫过,也彷徨过?尤其是生完二宝以后,看着自
英格兰vs塞内加尔球员跑动距离统计赖斯12km全场最高直播吧12月5日讯FIFA官方公布了英格兰30战胜塞内加尔比赛的球员跑动数据,英格兰队的赖斯以12km的跑动距离,成为本场比赛跑动距离最多的球员。英格兰球员跑动距离皮克福德5。4k
世界杯今夜或爆大冷!日本有望掀翻世界亚军太极虎恐惨败出局头条创作挑战赛北京时间12月5日,世界杯14决赛将进入第三个比赛日。备受关注的五星巴西将首次亮相,而亚洲和中国球迷关注的日本和韩国也将陆续亮相。日本队将挑战上届世界杯亚军克罗地亚队
汉献帝为何禅位于魏王?3205年乙酉岁汉献帝刘协建安十年,彗基先除紫微,218年戊戌岁汉献帝刘协建安二十三年,复扫太微。新天子气见东南以来,218年戊戌岁汉献帝刘协建安二十三年,白虹贯日,月蚀荧感,比年2