目标:
一、各种族系数量占比
二、各世代宝可梦数量
三、种族值解析
四、传说宝可梦相关分析,各时代占比,属性值与传说宝可梦的相关性,种族系与传说宝可梦的相关性
五、各世代推荐宝可梦
#导入三个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/pokemon1.xlsx")
一、各种族系数量占比
①各种族系的数量和占比:水系、一般系、草系为数量前三位,冰系、妖精系、飞行系为数量后三位,有点出乎意料, 飞行系 竟然是最少的。水系占比14.23%,一般系占比13.11%,草席占比9.74%。
#查看各系的数量
out = pokemon[['type1','is_legendary']].groupby('type1').count()
print(out)
②绘制一个柱形图来看看效果:
#查看各世代宝可梦不同种族数量
pokemon['type1'].value_counts().plot.bar()
③绘制饼图看看效果:
#查看各系的占比
fig,ax = plt.subplots(2,1,figsize=(15,15))
pokemon['type1'].value_counts().plot.pie(ax=ax[0],shadow=False,autopct='%1.2f%%')
ax[0].set_ylabel('') #设置y轴标签
ax[0].set_xlabel('type1') #设置x轴标签
sns.countplot('type1',data=pokemon,ax=ax[1])
ax[1].set_ylabel('')
ax[1].set_xlabel('type1')
plt.show()
二、各世代宝可梦数量
①第5世代是宝可梦数量最多的世代,第6世代是宝可梦数量最少的世代。
#计算一下各世代的宝可梦数量
pokemon['generation'].value_counts()
②柱形图看看效果:
#柱形图查看各世代宝可梦数量
pokemon['generation'].value_counts().plot.bar()
③计算一下各世代传说宝可梦数量:可以看到传说宝可梦最多的是第7世代,最少的是第1世代,有个比较明显的趋势是越往后的世代传说宝可梦越多(除了第6世代)。
#新建一个数据表格,用于保存世代generation与是否传说is_legendary两列数据
pokemon1=pokemon[['generation','is_legendary']]
pokemon1.head()
#建立数据透视表
pokemon_p=pokemon1.pivot_table(values='is_legendary', #计算的值
index='generation', #透视的行,分组的依据
aggfunc='sum') #聚合函数
pokemon_p
④对透视表进行降序排列:可以看到传说宝可梦最多的第7世代一共有17只,最少的第一世代只有5只。
# 对透视表进行降序排列
pokemon_p = pokemon_p.sort_values(by='is_legendary', # 排序依据
ascending=False # 是否升序排列
)
pokemon_p
⑤对新的透视结果做折线图展示:
#对新的透视结果做折线图展示
x=[1,2,3,4,5,6,7]
y=pokemon_p['is_legendary']
plt.plot(x,y)
plt.show()
三、种族值解析
①查看种族值的分布图:有点类似双峰分布,最多种族值分布在300和500附近。
#种族值分布
plt.hist(pokemon['base_total'],bins=35)
plt.xlabel('total_stats')
plt.ylabel('Frequency')
②通过小提琴图观察各个种族的种族值特性:可以看到龙系的整体种族值是相对较高的。
#不同种族的种族值分布
plt.subplots(figsize=(15,5))
sns.violinplot(x='type1',y=pokemon['base_total'],data=pokemon, palette='muted')
③通过数据透视表,了解完整的各种族的平均种族值情况,得出什么种族是最值得培育的,得到的结论是龙系的种族值均值高达522,是最值得培育的种族,其次是钢系、格斗系;而虫系是最可怜的种族,平均种族值仅有380,毒系、一般系也惨兮兮。
#建立数据透视表
#计算一下各系宝可梦种族值分布
#新建一个数据表格,用于保存世代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
④再看看各系种族值的描述型数据统计:种族值均值为437,中位数是434,各位小伙伴,低于这俩值的宝可梦你要是培育的话,那就真的是真爱了。
#各系种族值得描述性数据情况
pokemon_z.describe()
⑤推荐一些培育性价比比较高的宝可梦:种族值高于570,但非传说宝可梦的准神。
#找到非传说宝可梦但是种族值非常优秀,值得培育的宝可梦
pokemon[(pokemon['base_total'] >= 570) & (pokemon.is_legendary == 0)]['chinese_name'].head(100)
四、传说宝可梦相关分析
①各世代宝可梦数量及传说宝可梦对比图:
#查看各世代宝可梦数量
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世代的传说宝可梦占比最高,达到21%;而第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)
④分析不同种族与传说宝可梦的相关关系:得出的结论是种族与是否为传说宝可梦没有很强的相关性,相对来说超能力系psychic、龙系dragon是传说宝可梦的概率较高。
#将种族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)
参考资料: