python数据分析——pokemon数据分析
1.项目描述
精灵宝可梦系列是一套由日本GAME FREAK代表田尻智一同于1995年开发,日本任天堂株式会社于1996年推出的一款Game Boy(任天堂所推出之掌上型游戏机)游戏,其后发展为跨媒体制作的作品。
由于其独特的游戏系统广受大众的欢迎,年度产品销量近千万(红、绿二版本合计。全系列作目前累积已破亿)。任天堂趁此热潮,推出后续的一系列游戏、漫画、书籍、对战卡片及周边产品,还联合日本东京电视台推出电视动画,以及一年一度的剧场版动画电影,更在1998年成功进军美国,并拓展至世界各地(除了少数地方因为宗教等因素)。这套作品已成功打入全世界数十个国家,成为世界闻名的卡通形象和日本的国民动画。相关产品销售额达数十亿美元以上。因为各部分的成长,目前精灵宝可梦相关事业已经独立成一公司:精灵宝可梦股份有限公司(株式会社ポケモン),为任天堂旗下的子公司之一。
精灵宝可梦作品包括游戏、动画、漫画、卡片游戏及相关产品。宝可梦同时也是宝可梦世界所有虚构出来的物种所拥有的共同的名字。截至2017年10月,全系列的宝可梦共有805种。
基于此,我们可以对Pokémon的数据/变量进行统计分析,并从中发掘他们之间的关系,用可视化的方式进行直观的查看
2.数据集描述
kaggle提供数据集,数据集形式为CSV文件,当前数据集只包括了前6代的pokemon
数据字典
Number: Pokédex中的Pokémon ID,整型
Name: Pokémon名称,字符串
Type_1: 主要类别,字符串
Type_2: 副类别,字符串
Total: 基本统计值的和,整型。基本统计值包含以下6个属性:
- HP : 生命值,整型
- Attack: 攻击值,整型
- Defense: 防御值,整型
- Sp_Atk: 特殊攻击值,整型
- Sp_Def: 特殊防御值,整型
- Speed: 速度值,整型
- Generation: 属于第几代Pokémon,整型
- isLegendary: 是否为传说中的Pokémon,布尔值
- Color: Pokémon颜色,字符串
- hasGender: 是否有性别,布尔值
- Pr_male: 可能为男性的概率,浮点型
- Egg_Group_1: 蛋群分组1,字符串
- Egg_Group_2: 蛋群分组2(如果有的话),字符串
- hasMegaEvolution: 是否拥有Mega进化的能力,布尔值
- Height_m: Pokémon的高度(单位为m),浮点型
- Weight_kg: Pokémon的重量(单位为kg),浮点型
- Catch_Rate: 捕获率,整型
- Body_Style: 身体形状,字符串
3.代码实现
#引入我们所需要的包
import csv
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib notebook
#解决matplotlib显示中文问题
#仅适用于windows
plt.rcParms['font.sans-serif'] = ['SimHei'] #默认字体
plt.rcParms['axes.unicode_minus'] = Fales #解决保存图像是负号'-'显示为方块的问题
#读取数据,并打印前5行
pokemon = pd.read_csv('./data/pokemon.csv')
pokemon.head()
输出结果:
pokem数据前5行Type_1的数量统计图
sns.countplot(x = 'Type_1',data='pokemon')
plt.title = ('count of main types')
plt.xlabel("Main Types")
plt.ylabel("Nums")
plt.xticks(rotation = 60)
plt.show()
输出结果:
Type_1数量统计图结论:主属性为:water、Normal、Grass、Bug属性的pokemon数量最多
Type_2的数量统计图
sns.countplot(x="Type_2",data="pokemon")
plt.title = ('count of assistans types')
plt.xlabel('Type_2')
plt.ylabel('Nums')
plt.xticks(rotation = 60)
plt.show()
输出结果:
Type_2数量统计图结论:副属性为fly的pokemon数量远远大于其他的pokemon
Egg_Group_1的数量统计图
sns.countplot(x = 'Egg_Group_1',data = pokemon)
plt.title('count of egg_group_1')
plt.xlabel("egg_group_1")
plt.ylabel("Nums")
plt.xticks(rotation = 60)
plt.show()
输出结果
egg_group_1数量统计图egg_group_1为Field的pokemon数量远远大于其他的pokemon
Egg_Group_2的数量统计图
sns.countplot(x="egg_group_2",data = "pokemon")
plt.title('count of egg_group_2')
plt.xlabel('egg_group_2')
plt.ylabe('Nums')
plt.xticks(rotation=60)
plt.show()
输出结果:
egg_group_2数量统计图结论: egg_group_2为 Grass Oragon Field的数量最多
其他单变量数量统计图
plt.figure(figsize=(10,5))
#isLegendary 的数量统计图
ax1 = plt.subplot(2, 3, 1)
sns.countplot("isLegendary",data = pokemon)
plt.title("islegendary")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
plt.xticks(rotation = 60)
#hasGender 的数量统计图
plt.subplot(2, 3, 2, sharey=ax1)
sns.countplot("hasGender",data = pokemon)
plt.title("hasGender")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
plt.xticks(rotation = 60)
# hasMegaEvolution 的数量统计图
plt.subplot(2, 3, 3, sharey=ax1)
sns.countplot("hasMegaEvolution",data = pokemon)
plt.title("hasMegaEvolution")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
plt.xticks(rotation = 60)
# 颜色color 的数量统计图
plt.subplot(2, 3, 4)
sns.countplot("Color",data = pokemon)
plt.title("Color")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
plt.xticks(rotation = 60)
# 身形Body_Style 的数量统计图
plt.subplot(2, 3, 5)
sns.countplot("Body_Style",data = pokemon)
plt.title("Body_Style")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
plt.xticks(rotation = 60)
# 第n代Generation 的数量统计图
plt.subplot(2, 3, 6)
sns.countplot("Generation",data = pokemon)
plt.title("Generation")
plt.xlabel("")
plt.ylabel("")
plt.tick_params(labelsize=5)
输出结果:
数值型数据分布图
# 绘制数值型数据概率分布图
# 使用subplot绘制成4行3列
# 数值型数据有:
# 'Total', 'HP', 'Attack', 'Defense', 'Sp_Atk', 'Sp_Def', 'Speed', 'Pr_Male', 'Height_m', 'Weight_kg', 'Catch_Rate'
# 使用dropna()将数据中的缺失值去掉
from scipy import stats
plt.figure(figsize=(10,5))
list1 = ['Total', 'HP', 'Attack', 'Defense', 'Sp_Atk', 'Sp_Def', 'Speed', 'Pr_Male', 'Height_m', 'Weight_kg', 'Catch_Rate']
for item_num in range(0,len(list1)) :
plt.subplot(4,3,item_num+1)
pokemon1 = pokemon.dropna(subset = [list1[item_num]])
column_name = list1[item_num]
sns.distplot(pokemon1[column_name],hist = True,kde = True)
plt.tick_params(labelsize = 5)
if stats.shapiro(pokemon1[column_name])[1]<0.05:
print('{}不服从正态分布'.format(list1[item_num]))
else:
print('{}服从正态分布'.format(list1[item_num]))
输出结果:
变量间的相关系数
# 计算以上各数值型变量间的相关系数,观察变量间的关系
df_num_var = pokemon[list1]
df_num_var = df_num_var.dropna()
print(df_num_var.corr("spearman"))
print('\n')
for i in range(0,len(list1)):
for j in range(i+1,len(list1)):
spearman_corr=stats.spearmanr(df_num_var[list1[i]],df_num_var[list1[j]])
if spearman_corr[1]<0.05:
print('{}和{}存在显著相关关系,相关系数为{}'.format(list1[i],list1[j],spearman_corr[0]))
else:
print('{}和{}不存在显著相关关系,相关系数为{}'.format(list1[i],list1[j],spearman_corr[0]))
print('\n')
输出结果:
结论:
结论一: HP除了和Pr_Male不存在显著相关关系之外,与其他所有的指标都存在显著性关系
结论二: Attack与所有的指标都存在显著性关系
结论三: Defense除了和Pr_Male、Speed不存在显著相关关系之外,与其他所有的指标都存在显著性关系
结论四: Sp_Def除了和Pr_Male不存在显著相关关系之外,与其他所有的指标都存在显著性关系
结论五: Sp_Atk和所有指标都存在显著性关系
结论六: Speed与Pr_Male、Height_m、Weight_kg、Catch_Rate这几个指标相互之间都存在显著性关系。
很多时候,我们在进行游戏的时候,赋值加点并没有一套完整的说法与攻略,经过各个指标的相关性检验。根据以上的相关性数值,玩家在进行pokemon游戏时,可以通过选择pokem的性别,种类,以及pokemon的一些能力赋值,培养出更强的精灵。