作为童年玩Pokemon长大的孩子,经历了火焰版、叶绿版、红宝石、蓝宝石、绿宝石,五个版本的GBA游戏洗礼,对于Pokemon有着深深的情怀,偶然看到有这么一个数据集,试试看,看看分析出来的东西和我所想是不是一样的。虽然这个分析半夜三更进行,腰酸腿痛的,但是,爽!
1.数据整理和查看
1.导入所需要的package
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pyecharts
#echart只是为了一个比较酷炫的雷达图
%matplotlib notebook
#notebook模式更方便图片的导出
2.读取数据
data = pd.read_csv('pokemon_list.csv')
data.head()
居然名字都是英文版的,但是也没有什么问题,资深玩家无所畏惧,第一个肯定是妙蛙种子,不信你百度看看。
还有就是这个数据是721个,所以没有一些新的小精灵和mega升级版本。
data.info()
每一列的数据基本可以有个了之,分别是Number编号、Name名称、Type_1类别1、Type_2类别2(蒸汽系就是火焰系加上水系)、Total数值总计、HP血量、Attack攻击、Defense防御、Sp_Atk魔法攻击、Sp_Def魔法防御、Speed速度、Generation几代、isLegendary是否是神兽、Color颜色、Pr_male为男性精灵的几率、Egg_Group_1蛋的第一种类、Egg_Group_2蛋的第二种类、hasMegaEvolution有超进化(总觉得是数码宝贝)、Height_m高度以米为单位、Weight_kg重量以公斤为单位、Catch_Rate捕获几率、Body_Style身体形态(百变怪最牛逼)
基本看出只有350个有类别2的属性,大部分为单一属性精灵,191个有第二种类的蛋,对于两种属性的缺失值,都是统一属性的多分类,可用第一分类作为填充。
#缺失值处理策略为前一列种类填充后一列
data['Type_2'] = data['Type_2'].fillna(value = data['Type_1'])
data['Egg_Group_2'] = data['Egg_Group_2'].fillna(value = data['Egg_Group_1'])
3.数据描述性统计列表
Total一列75%线在499,而最大值为720,高数值一类应该是神兽(玩过的都知道,神兽特么一张嘴一个岛就没了。。。)数值包括血量、攻击等,标准差基本为28左右,这一点还是很良心,让玩家有良好的从小怪到大怪有一个阶梯形的概念。其他的都是单独特性,在这里要说一下捕获率Catch_Rate,口袋妖怪的设定是从血量多到血量少,捕获率会提升,最小为3,最大为255,应该是从2的一次方+1,一直到2的八次方-1。不然通俗理解为255%,丢个球,捕获率抓到两个半多?!两个我还能理解,半个多是什么意思?!买一赠一还送个小的?!情侣入住,房租减半?!一家人整整齐齐?!
2.数据分析
2.1种类分析
Type_pd=pd.concat([data.Type_1,data.Type_2],axis=1)
#计算出第一种类的数量加上第二种类数量
Type_count = data.Type_2.value_counts() + data.Type_1.value_counts()
Type_count.sort_values(ascending = False)
由于失误,第一次只计算第一类别,发现飞行类的只有3个,但是鸟类中最爱的比比鸟居然不是飞行类,进行单独查看后,发现比比鸟第一类别是normal,第二类别就是飞行,所以将两者进行累加,能够看出来,水生类最多,幽灵类最少。毕竟幽灵类的,没有道具无法进行捕获。
2.2可视化分析
#Series序列中添加0,并对指作排序处理,便于绘图
Type_count = data.Type_2.value_counts() + data.Type_1.value_counts()
Type_count = pd.Series([0]).append(Type_count).sort_values()
#画布大小设置
plt.figure(figsize=(14,5))
#类别设置
cata = [0,'Ghost','Steel','Ice','Dragon','Fairy',
'Dark','Fighting','Rock','Electric','Ground','Poison',
'Bug','Fire','Flying','Psychic','Grass','Normal','Water']
#坐标轴y值由Series中的值作为代替
y_pos = Type_count
#设置横坐标和纵坐标,颜色,透明度
plt.bar(cata,y_pos,facecolor = 'yellowgreen',alpha=0.4)
#设置横坐标类别进行映射
plt.xticks(cata)
#x轴名称
plt.xlabel('Type')
#x的横向数量
plt.xlim(0,18)
#总体图形名称
plt.title('the num of Type')
#进行展示
plt.show()
plt.figure(figsize=(10,10))
#标签名称
cata = ['Ghost','Steel','Ice','Dragon','Fairy',
'Dark','Fighting','Rock','Electric','Ground','Poison',
'Bug','Fire','Flying','Psychic','Grass','Normal','Water']
#分块数据
sizes = Type_count.drop(0)
#颜色设置
colors = [ '#ff8100', '#057d9f', '#00bd39', 'yellow', 'lightgreen', 'orange', '#64de89']
#各个色块的偏移
explode = (0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0.1)
#画饼图
plt.pie(sizes, explode=explode, labels=cata, colors=colors,
autopct='%1.1f%%', shadow=False, startangle=90)
#呈现正圆形的图形
plt.axis('equal')
#标题
plt.title("Percentage of Different Types of Pokemon")
plt.show()
可以看出整体,水系精灵最多,其次是Normal正常系精灵,也符合游戏大陆海洋分布的设定。
2.2.多属性结合分析
- 种类结合性别分析
- 种类结合数值分析
2.2.1结合性别分析
因为对于有性别的精灵分析类别价值不大,所以故对于无性别精灵进行分析
nogender_num = data[data['hasGender']==False].groupby('Type_1',as_index = False).Number.count().s ort_values(by='Number',ascending = False)
对于类别Type_1进行分类(再次不对第二类别做分析,因为第二类别往往是因为精灵在进化和相应的环境中,才会出现第二类别。)
#进行可视化图表建立
#修改列名便于观察
nogender_num.rename(columns={'Type_1':'Type'},inplace=True)
#设置画布
plt.figure(figsize=(12,8))
#
sns.set(font_scale=1.2,color_codes='#df1234')
sns.barplot(x='Type',y='Number',data = nogender_num)
可以看出Steel钢铁类和Psychic超能力类高于其他类别,主要是钢铁类和超能力类的设定,钢铁类趋向于一种分化和类似于修炼的方式来进行,而超能力就像他的设定一般,不详。
2.2.2结合数值分析
#调用seaborn画箱线图分析数值total和种类的关系
#map映射种类和数值
type_to_dict = { 'Grass': 0, 'Fire': 1, 'Water': 2, 'Bug': 3, 'Normal': 4,
'Poison': 5, 'Electric': 6, 'Ground': 7, 'Fairy': 8, 'Fighting': 9,
'Psychic' : 10, 'Rock': 11, 'Ghost':12, 'Ice' : 13, 'Dragon': 14,
'Dark': 15, 'Steel': 16, 'Flying': 17}
data['Int_Type1'] = data['Type_1'].map(type_to_dict).astype(int)
#设置相关的sns参数
sns.set(style="ticks")
fig, ax = plt.subplots(figsize=(8,6))
sns.boxplot(ax = ax, x="Int_Type1", y="Total",data=data, palette="PRGn")
sns.despine(offset=10, trim=True)
plt.show()
可以看出平均水平普遍较高的是龙类(大家都是龙图腾的国度)。
#进行分类别计算各个数值的均值
sum_abili = data[['HP','Attack','Defense','Sp_Atk','Sp_Def','Speed']].groupby(data['Type_1'],as_index=True).mean().round(2)
#use
colorlist = ['#313695', '#abd9e9', '#ffffbf',
'#fdae61','#d73027', '#a50026',
'#314693', '#3bd9e9', '#f23fbf',
'#fda231','#d73a27', '#f51026',
'#312d93', '#3bd9ea', '#f23abf',
'#fda2f1','#df1a27', '#a50f26',]
c_schemas= [{"name": "生命值/HP", "min": 0},
{"name": "攻击值/Attack", "min": 0},
{"name": "防御值/Defense", "min": 0},
{"name": "特殊攻击值/Sp.Atk", "min":0},
{"name": "特殊防御值/Sp.Def", "min":0},
{"name": "速度/Speed", "min":0}]
radar = Radar('不同次代小精灵属性均值情况',width=800 ,height=600,
title_pos='center')
radar.config(c_schema=c_schemas, shape='polygon')
for i in range(18):
radar.add(sum_abili.index[i], [list(sum_abili.iloc[i,:])], item_color=colorlist[i],symbol=None,
legend_pos='0%',legend_orient='vertical')
radar
可以看出,总体类别中,攻击值和生命值的差别不大,毕竟在宠物小精灵中,更多的是释放技能,而不是单纯的撞击,速度的差异性最大,飞行系因为特殊的属性的速度最快,而后是电系和龙系,能够释放电光火石技能的也就这几个类别。
#单独将Type_1,各数值,Generation合成一个表
data_ex = data[['Type_1','HP','Attack','Defense','Sp_Atk','Sp_Def','Speed','Generation']]
查看数值变量按照pairs组合后的分布特征
sns.pairplot(data_ex,vars=['HP','Attack','Defense','Sp_Atk','Sp_Def','Speed'],hue = 'Type_1')
查看每个数值型变量的分布特征
#单独抽出数值做成feature表
feature = data_ex.columns[1:7]
plt.figure(1,figsize=(18,18))
#设置x轴线风格
sns.axes_style('ticks')
for i in range(len(feature)):
tmp = data[feature[i]]
#画出画布
plt.subplot(3,3,i+1)
#在画布中画出柱状图和密度分布线
sns.distplot(tmp)
plt.show()
数值相关性分析
#相关性分析
data[['Total','HP','Attack','Defense','Sp_Atk','Sp_Def','Speed']].corr()
#热力图绘制
plt.figure(figsize=(10,10))
plt.title('num_heatmap')
sns.heatmap(corr,square=True,linewidths=.5,cmap="YlGnBu")
plt.show()
- 尝试聚类和精灵特征来进行分类
- 尝试构建新的特征
未完待续。。。