[PYTHON] J'ai analysé les données de combat de rang du bouclier d'épée Pokemon et je les ai visualisées sur Tableau

Too Long, Didn’t Read

Bonjour, je me demande Shokei qui se réfère à cet article Pokemon, raccourci par Pokemon (Pokemon · Pokémon est. Marque déposée de Nintendo, Creatures, Game Freak) il y a joué.

Le deuxième patch d'extension du dernier Pocket Monster Sword Shield (communément connu sous le nom de bouclier d'épée), le champ de neige de la couronne, a été publié le 23 octobre la semaine dernière, et de nombreux entraîneurs Pokemon sont revenus dans la région de Garal au cours de cette période. n'est-ce pas.

Comme d'habitude, je suis l'un d'entre eux, et mon Pokémon bien-aimé électrique (noir et jaune foiré un gars cool) J'ai entendu dire qu'il serait possible de l'utiliser, et j'ai l'impression que c'était juste avant de commencer le jeu debout à l'envers.

Mis à part le côté, ce bouclier d'épée de travail a une fonction appelée correspondance de rang qui permet des batailles interpersonnelles en ligne (le classement est déterminé par le record de bataille car il ne s'agit que d'un rang), et c'est le contenu final qui est également un élément de ce travail. Un mois est une saison, et le rang est réinitialisé et le Pokémon qui peut être utilisé est modifié au tournant de la saison, et l'environnement change considérablement à chaque saison, ce qui est une grande différence par rapport à la correspondance de notation du travail passé.

Comme je l'ai mentionné plus tôt, je n'ai pas touché Pokemon depuis longtemps depuis que je me suis installé sur l'île de l'armure (le premier patch d'extension), donc la tendance et le soi-disant "[méta] dans le match de rang du bouclier d'épée Pokemon où l'environnement change rapidement. ](Https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF) ”n'est pas connu, il est donc difficile de formuler une stratégie.

Bien sûr, comme vous le savez, après la distribution de Pokemon HOME en février de cette année, les données relatives aux combats seront divulguées sur l'application de la version smartphone. Il est désormais possible de collecter des informations telles que les 10 meilleurs taux de recrutement et le type de techniques dont vous vous souvenez.

Cependant, j'ai senti que ce n'était pas suffisant. Est-il possible de créer quelque chose de plus complet et de refléter davantage le «niveau»? Une telle prise de conscience du problème est la principale motivation pour commencer cet article.

Goal

Chose finie (spoiler)

Tableau Public

gif2.gif

Fixation d'objectifs

Le point de départ cette fois est

était.

Le point d'atterrissage est donc

Il semble que.

Solution du problème

Cependant, afin de capturer la tendance et la méta de chaque saison, ce qui est l'objectif de ce livre, il semble que nous devions nous fier aux données de Pokemon HOME, les données liées au combat publiées à l'extérieur par Pokemon sont les miennes. Autant que je sache, c'est tout.

Si vous vous référez à Pioneer qui a acquis les données de combat de correspondance de rang de l'API, il semble que les données Pokemon HOME + α puissent être obtenues.

Cette fois, je traiterai les données obtenues à partir de cela pour les rendre visibles afin que quelque chose comme "Tier" puisse être compris (divers).

Je pense qu'il existe plusieurs méthodes de visualisation, mais j'ai décidé d'utiliser Tableau Desktop après avoir évalué de manière exhaustive la commodité d'un fonctionnement interactif, de bons visuels et de nombreuses fonctions (ou plutôt, reflétant mon goût). ..

Je présenterai à nouveau cet objectif.

Let's Try it

1. À propos de l'API

Pour le téléchargement des données suivantes, reportez-vous à l'article @retrorocket (7 juin 2020). Veuillez lire ici pour plus de détails.

curl 'https://api.battle.pokemon-home.com/cbd/competition/rankmatch/list' \
  -H 'accept: application/json, text/javascript, */*; q=0.01' \
  -H 'countrycode: 304' \
  -H 'authorization: Bearer' \
  -H 'langcode: 1' \
  -H 'user-agent: Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Mobile Safari/537.36' \
  -H 'content-type: application/json' \
  -d '{"soft":"Sw"}'

La réponse obtenue à partir de la demande API ci-dessus contient des informations sur la saison de correspondance de classement.


{
  "code": 200,
  "detail": 0,
  "list": {
    "7": {
      "10072": {
        "name": "Saison 7",
        "start": "2020/06/01 13:00",
        "end": "2020/07/01 08:59",
        "cnt": 147244,
        "rule": 1,
        "season": 7,
        "rst": 0,
        "ts1": 1591187503,
        "ts2": 1591187515,
        "reg": "000000248"
      },
      "10071": { //ID de combat unique
        "name": "Saison 7",
        "start": "2020/06/01 13:00",
        "end": "2020/07/01 08:59",
        "cnt": 147202,
        "rule": 0,
        "season": 7,
        "rst": 0,
        "ts1": 1591187503,
        "ts2": 1591187515,
        "reg": "000000247"
      }
    }, //Ce qui suit est omis
}

La valeur de l'ID de saison et du premier, etc. inclus ici

"https://resource.pokemon-home.com/battledata/ranking/{season_id}/{rst}/{ts2}/pdetail-{values 1-5}"

Vous pouvez obtenir des données de Pokemon HOME en vous plongeant dans et en appuyant sur l'API.

2. Téléchargement des données

C'est un code correctement écrit, alors n'ayez pas peur

(Le dossier resources et le dossier resources \ split sont créés à l'avance dans le répertoire courant.)

import urllib.request
import json
import datetime
import os

def load_ids():
    ids = "";
    #Charger le json obtenu à partir de la requête API précédente
    with open(ID_FILEPATH, 'r', encoding='utf-8') as json_open:
        return json.load(json_open)

def check_dir(path):
    if not os.path.isdir(path):
        os.makedirs(path)

def get_response(url, file_name):
    try:
        with urllib.request.urlopen(url) as response:
            body = json.loads(response.read())
            with open(f'resources//split//{file_name}', 'w') as f:
                json.dump(body, f, indent=4)
        return True
    except urllib.error.URLError as e:
        print(e.reason)
        return False

def make_json(ids):
    for season_number in ids['list'].keys():
        for  season_id in ids['list'][season_number].keys():
            rst = ids['list'][season_number][season_id]['rst']
            ts2 = ids['list'][season_number][season_id]['ts2']
            for i in range(1,6,1):
                url = f'https://resource.pokemon-home.com/battledata/ranking/{season_id}/{rst}/{ts2}/pdetail-{i}'
                file_name = f'Season{season_number}_{"Single" if season_id[4]=="1" else "Double"}_{i}.json'
                if get_response(url, file_name):
                    with open('log', 'a') as f:
                        print(f'{datetime.datetime.now()} | Generated: {file_name}', file=f)

def merge_json(ids):
    for i in ids['list'].keys():
        for j in ids['list'][i].keys():
            rule = "Single" if j[4] == '1' else "Double"
            files = []
            for n in range(1,6,1):
                with open(f'.//resources//split//Season{i}_{rule}_{n}.json', 'r', encoding='utf-8') as json_open:
                    files.append(json.load(json_open))
            jsonMerged = {**files[0], **files[1], **files[2], **files[3], **files[4]}
            file_name = f'Season{i}_{rule}_master.json'
            with open(f'resources//{file_name}', 'w') as f:
                json.dump(jsonMerged, f, indent=4)
            with open('log', 'a') as f:
                print(f'{datetime.datetime.now()} | Merged   : {file_name}', file=f)

if __name__ == "__main__":
    ids = load_ids()
    #Veuillez spécifier votre répertoire préféré ici
    for path in ['.//resources', './/resources//split']:
        check_dir(path)
    make_json(ids)
    merge_json(ids)
    print('Suceeded')

L'exécution du script ci-dessus enregistrera le fichier json des données de combat de la saison 1 à la dernière saison.

Cependant, le problème est que le fichier json est divisé en 5 parties chaque saison, ce qui est très gênant.

Fusionnons-les en un seul fichier par saison.

def merge_json(ids):
    for i in ids['list'].keys():
        for j in ids['list'][i].keys():
            rule = "Single" if j[4] == '1' else "Double"
            files = []
            for n in range(1,6,1):
                with open(f'.//resources//split//Season{i}_{rule}_{n}.json', 'r', encoding='utf-8') as json_open:
                    files.append(json.load(json_open))
            jsonMerged = {**files[0], **files[1], **files[2], **files[3], **files[4]}
            with open(f'resources//Season{i}_{rule}_merged.json', 'w') as f:
                json.dump(jsonMerged, f, indent=4)


ids = "";
with open(ID_FILEPATH, 'r', encoding='utf-8') as json_open:
    ids = json.load(json_open)

make_jsonchunk(ids)

Avec cela, le grand nombre de fichiers json mentionnés précédemment aurait dû être agrégé un par un.

Le contenu de ce json est le suivant.

//Cette fois pokemon un json combiné de la saison appropriée.Nommé json
// .\Datachunk\pokemon.json
{
    "Numéro du livre d'images" : {
        "p_detail_id":{
            "temoti":{
                //Top 10 des techniques utilisées
                "waza":[
                    {
                        "id":"xxxx",
                        "val":"value"  //Taux de recrutement, pourcentage
                    },
                    ...
                ],
                //Caractéristiques adoptées
                "tokusei":[
                    {
                        "id": "xxxx",
                        "val": "value" //Taux de recrutement, pourcentage
                    },
                    ...
                ],
                //Top 10 des Pokémon dans vos affaires
                "motimono": [
                    {
                        "id": "xxxx",
                        "val": "value" //Taux de recrutement, pourcentage
                    },
                    ...
                ],
                //Top 10 des Pokémon de l'équipe de combat ensemble
                "pokemon": [
                    {
                        "id": "xxxx",
                        "form": "value" //Forme
                    },
                    ....
                ]
            },
            "lose": {
                //Top 10 des techniques pour vaincre ce Pokémon
                "waza": [
                    {
                        "id": "xxxx",
                        "val": "value" //pourcentage
                    },
                    ...
                ],
                //Top 10 des Pokémon qui ont vaincu ce Pokémon
                "pokemon": [
                    {
                        "id": "xxxx",
                        "form": "value" //Forme
                    },
                    ...
                ],
            },
            "win": {
                //Top 10 des techniques vaincues par ce Pokémon
                "waza": [
                    {
                        "id": "xxxx",
                        "val": "value" //pourcentage
                    },
                    ...
                ],
                //Top 10 des Pokémon vaincus par ce Pokémon
                "pokemon": [
                    {
                        "id": "xxxx",
                        "form": "value" //Forme
                    },
                    ...
                ]
            }
        }
    }
}

Il semble que vous puissiez obtenir diverses informations telles que les techniques utilisées pour Pokemon en dehors du TOP10 et Pokemon utilisées ensemble, qui ne peuvent pas être obtenues chez Pokemon HOME.

En résumé, les données qui peuvent être acquises sont les suivantes

  1. Les 10 techniques les plus utilisées
  2. Caractéristiques adoptées
  3. Top 10 des Pokémon dans vos affaires
  4. Top 10 des Pokémon inclus dans l'équipe de combat ensemble
  5. Top 10 des techniques pour vaincre ce Pokémon
  6. Top 10 des Pokémon qui ont vaincu ce Pokémon
  7. Top 10 des techniques vaincues par ce Pokémon
  8. Top 10 des Pokémon vaincus par ce Pokémon

Tirez pleinement parti de ces données et essayez de calculer le niveau le plus plausible.

Cependant, cette fois, la méthode de calcul des niveaux n'est pas le sujet principal, je vais donc considérer un indice qui semble donner un résultat comme celui-là.

3. Sélection du niveau

--Problème: je veux que Pokemon avec un taux de recrutement élevé et un taux de sélection élevé arrive en tête.

Comment calculer meta

Pensez à la méta

Niveau 1, c'est-à-dire environnement méta principale Fait référence au Pokémon le plus fort et le plus populaire, nous allons donc créer un index centré sur «fort» et «à la mode».

"fort"

Les données que j'ai cette fois incluent "Top 10 des Pokémon qui ont vaincu ce Pokémon". Le nombre de défaites et le nombre d'adversaires pouvant être vaincus sont considérés comme remplaçant la force du Pokémon dans l'environnement.

"Est à la mode"

L'indicateur le plus intuitif des critères «populaires» est le recrutement des partis, mais cette fois, les données ne sont pas disponibles et devraient être remplacées par d'autres critères. Étant donné que ces données incluent "Top 10 des Pokémon utilisés avec ce Pokémon", nous avons décidé de calculer le Pokémon considéré comme utilisé par un large éventail de parties à partir des données de classement basées sur ces données. .. De plus, on considère que le nombre de sélections augmente proportionnellement au nombre de défaites mentionnées ci-dessus, de sorte que le taux de recrutement du parti seul est utilisé comme un indice pour savoir s'il est "populaire" ou non.

Procès

Importation de bibliothèque

import json
import csv
import pandas as pd
from sklearn import preprocessing

Lecture des données

pokedex = "";
with open('.//Datachunk//bundle.json', 'r', encoding='utf-8') as json_open:
    pokedex = json.load(json_open)

pokedex = "";
with open('.//Datachunk//bundle.json', 'r', encoding='utf-8') as json_open:
    pokedex = json.load(json_open)

pdetail = "";
with open('.//Datachunk//pokemon.json', 'r', encoding='utf-8') as json_open:
    pdetail = json.load(json_open)

Fonction de sortie de fichier

def make_csv(pdetail, filename, method = 'temoti'):
    # method = 'temoti', 'win', 'lose'
    write_csv(["Book Number","Pokemon", "component", "value_or_rank"], filename, "w")
    for pokenum in  list(pdetail.keys()):
        for p_detail_id in list(pdetail[pokenum].keys()):
            t_name = get_pokemonname(pokenum, p_detail_id)
            for rank, poke_associations in enumerate(list(pdetail[pokenum][p_detail_id][method]['pokemon'])):
                a_name = get_pokemonname(poke_associations['id'], poke_associations['form'])
                write_csv([pokenum, t_name, a_name, rank+1] , filename, "a")

Calcul de l'indice de tendance et fonction de sortie

def make_index(filename):
    df = pd.read_csv(filename, encoding='utf-8')
    concated_df1 = df.groupby('component', as_index=False)['value_or_rank'].mean()
    concated_df1.columns = ['Pokemon', 'RankAverage']

    concated_df2 = df.groupby('component', as_index=False)['value_or_rank'].sum()
    concated_df2.columns = ['Pokemon', 'Top10Count']

    concat_df = pd.concat([concated_df1,concated_df2], axis = 1, join = 'inner')
    concat_df =pd.concat([concated_df1[concated_df1.columns[0]], \
                concat_df.drop(concat_df.columns[2], axis =1)], axis = 1)

    concat_df['RankAverage_std'] = preprocessing.minmax_scale(concat_df['RankAverage'])
    concat_df['Top10Count_std'] = preprocessing.minmax_scale(concat_df['Top10Count'])

    concat_df['Crt'] = concat_df["RankAverage"] * concat_df["Top10Count"]
    concat_df['Crt_by_std'] = concat_df['RankAverage_std'] * concat_df['Top10Count_std']
    return concat_df.sort_values('Crt', ascending = False)

Courir

make_csv(pdetail, "test1.csv", 'lose')
make_index('test1.csv').to_csv('test2.csv', index=False)
Pokémon Classement moyen du recrutement Classement de recrutement TOP10 count RankAverage_std Top10Count_std Crt Crt_by_std
Drews 4.863158 462 0.429240 0.956432 2246.778947
Loebsin 5.742424 379 0.526936 0.784232 2176.378788
Samayor 4.747368 451 0.416374 0.933610 2141.063158
... ... ... ... ... ...

スクリーンショット_2020_10-27_185731.png

* Remarque: ce qui précède est créé à partir de données de double bataille

Il semble que les combats aient été le choix de Rob Singh cette saison.

Je sens que cela peut être reflété grossièrement.

Calcul du méta-index

Le méta-index est calculé à partir du [nombre d'ennemis vaincables] * [rang] normalisé.

Le résultat est sorti de la même fonction qu'auparavant.

スクリーンショット_2020_10_28_043415.png

Le nombre de Pokémon répertoriés dans le classement était inférieur au classement de recrutement. C'est un peu surprenant que Laplace soit le plus gros, mais j'ai l'impression que c'est le double.

C'est une méthode de calcul trop approximative, mais j'essaye des choses, j'ai donc décidé d'utiliser ces deux indicateurs pour le moment.

Visualisation

Nuage de points

Quant à la façon de donner une forme arbitraire à la forme du diagramme de dispersion, elle s'écarte du sujet principal, je vais donc l'écrire à nouveau un jour.

Veuillez consulter ici pour des informations urgentes.

J'ai également emprunté l'icône Pokemon ici.

スクリーンショット_2020-10-29_205435.png

Clustering

J'ai défini le nombre de clusters sur 10 et essayé le clustering. Il semble que je puisse ajouter un niveau (je pense).

スクリーンショット_2020-10-29_205057.png

Saison règle Pokémon Classement moyen du recrutement Classement de recrutement TOP10 count RankAverage_std Top10Count_std Crt Crt_by_std
Saison 1 Célibataire Drews 4.863158 462 0.429240 0.956432 2246.778947
Saison 1 Célibataire Loebsin 5.742424 379 0.526936 0.784232 2176.378788
Saison 1 double Samayor 4.747368 451 0.416374 0.933610 2141.063158
Saison 2 Célibataire ... ... ... ... ... ...

Génération de données

L'indice précédent est produit pour les simples et les doubles pour toutes les saisons. Vous pouvez le faire un par un à la main, mais c'est gênant, alors préparez un programme.

def Rename(x):
    for key in rename_dict.keys():
        if x[2] == key:
            x[2] = rename_dict[key]
    return x[2]

rename_dict = {'Nyaonics':'Nyaonics♂',
'Gilgard':'Gilgard盾',
'Hihi Dharma':'Hihi DharmaN',
'Basrao':'Basrao赤',
'Lugargan':'Lugargan昼',
'Metheno':'Metheno(météore)',
'Yessan':'Yessan♂'}

En passant, j'utilise cette fonction pour le renommer car c'est un peu difficile à visualiser sur Tableau. Je n'y toucherai pas cette fois, donc j'espère que vous pourrez penser "Je ne change pas de nom".

def cal_crt(df, method='temoti'):
    if method == 'temoti':
        row_name = "Index épidémique"
    elif method == 'win':
        row_name = 'Index méta'

    concated_df1 = df.groupby('B', as_index=False)['value'].mean()
    concated_df1.columns = ['Pokemon', 'RankAverage']

    concated_df2 = df.groupby('B', as_index=False)['value'].sum()
    concated_df2.columns = ['Pokemon', 'Top10Count']

    concat_df = pd.concat([concated_df1,concated_df2], axis = 1, join = 'inner')
    concat_df =pd.concat([concated_df1[concated_df1.columns[0]], \
                concat_df.drop(concat_df.columns[2], axis =1)], axis = 1)

    concat_df['RankAverage_std'] = preprocessing.minmax_scale(concat_df['RankAverage'])
    concat_df['Top10Count_std'] = preprocessing.minmax_scale(concat_df['Top10Count'])

    concat_df['Crt'] = concat_df["RankAverage"] * concat_df["Top10Count"]
    concat_df[row_name] = concat_df['RankAverage_std'] * concat_df['Top10Count_std']
    df = concat_df.sort_values('Crt', ascending = False)
    return df.drop(['RankAverage', 'Top10Count', 'RankAverage_std', 'Top10Count_std', 'Crt'], axis=1)
def get_name(num, p_detail_id, method='pokemon'):
    if method == 'pokemon':
        name = ''
        if num == "876":
            if p_detail_id == "0":
                name = "Yessan ♂"
            else:
                name = "Yessan ♀"
        elif num == "479":
            if p_detail_id == "0":
                name = "Rotom (par défaut)"
            elif p_detail_id == "1":
                name = "Rotom (mar.)"
            elif p_detail_id == "2":
                name = "Rotom (mercredi)"
            elif p_detail_id == "3":
                name = "Rotom (glace)"
            elif p_detail_id == "4":
                name = "Rotom (volant)"
            elif p_detail_id == "5":
                name = "Rotom (herbe)"
        else:
            name = pokedex['poke'][int(num) -1]
    elif method == 'motimono':
        name = pokedex['item'][num]
    else:
        name = pokedex[method][num]

    return name
def data_trans(pdetail, method1 = 'temoti', method2='pokemon', column =  ["A", "B", "value"]):
    t_names = []
    a_names = []
    ranks = []
    for pokenum in  list(pdetail.keys()):
        for p_detail_id in list(pdetail[pokenum].keys()):
            t_name = get_name(pokenum, p_detail_id, method='pokemon')
            for rank, component in enumerate(list(pdetail[pokenum][p_detail_id][method1][method2])):
                a_name = get_name(component['id'], component[list(component.keys())[1]], method=method2)
                t_names += [t_name]
                a_names += [a_name]
                ranks += [rank+1]
    return pd.DataFrame(
        data = {column[0]: t_names,column[1]: a_names,  column[2]: ranks},
        columns = column
    )
from pathlib import Path
import os
import re
#Sélectionnez votre propre répertoire
file_dir = ".//resources"
p = Path(file_dir)
files = sorted(p.glob("*"))

Seasons = []
Rules = []
df_master = pd.DataFrame(columns = ['Season', 'Rule', 'Pokemon','Index épidémique', 'Index méta'])
for rule in ['Single', 'Double']:
    for season_num in range(1,12,1):
        for method in ['temoti', 'win']:
            with open(f'{file_dir}//Season{season_num}_{rule}_master.json', 'r', encoding='utf-8') as json_open:
                data = json.load(json_open)
            if method == 'temoti':
                df_fashion = cal_crt(trans_data(data, method=method), method=method)
            elif method == 'win':
                df_meta =  cal_crt(trans_data(data, method=method), method=method)

        df = pd.merge(df_fashion, df_meta, on='Pokemon', how='outer').fillna(0)

        df['Season'] = season_num
        df['Rule'] = rule

        df_master = pd.concat([df_master, df], axis = 0)

df_master['Pokemon']  = df_master.apply(Rename,axis=1)
df_master.to_csv(f'ALL_SEASON_METAVALUES.csv', index=False)

4. Tableau de bord

Nous avons décidé de créer un tableau de bord qui affiche des informations telles que Pokémon qui sont faciles à adopter lorsque vous passez la souris sur le Pokémon sur le diagramme de dispersion ci-dessus.

Etude des spécifications

Pour le moment, je souhaite afficher les données suivantes qui peuvent être lues à partir de données brutes.

  1. Top 10 des techniques utilisées
  2. Caractéristiques adoptées
  3. Top 10 des Pokémon de votre inventaire
  4. Top 10 des Pokémon inclus dans l'équipe de combat ensemble
  5. Top 10 des techniques pour vaincre ce Pokémon
  6. Top 10 des Pokémon qui ont vaincu ce Pokémon
  7. Top 10 des techniques vaincues par ce Pokémon
  8. TOP10 Pokémon vaincu par ce Pokémon

Génération de données

Créez un fichier csv pour faciliter la gestion lors de la génération de données.

new_dict = {}
for n in pokedex['item'].keys():
    n = int(n)
    if n < 148:
        pass
    elif n < 260:
        id_ = n-143
        new_dict[id_] = pokedex['item'][str(n)]
    elif 264 < n:
        id_ = n-148
        new_dict[id_] = pokedex['item'][str(n)]

pd.DataFrame(new_dict.values(), index=new_dict.keys(), columns = ['item']).to_csv('item_index.csv')

pd.DataFrame(pokedex['waza'].values(), index=pokedex['waza'].keys(), columns = ['waza']).to_csv('skill_index.csv')

pd.DataFrame(pokedex['tokusei'].values(), index=pokedex['tokusei'].keys(), columns = ['tokusei']).to_csv('tokusei_index.csv')

À portée de main

%%timeit

Seasons = []
Rules = []
column_a = {'waza': 'Techniques à taux d'adoption élevé','pokemon':'Pokémon avec un taux de combinaison élevé' , 'tokusei':'Caractéristiques avec un taux d'adoption élevé' , 'motimono':'Quoi apporter avec un taux d'adoption élevé'}
file_names = {'waza':'ALL_SEASON_SKILL.csv','pokemon':'ALL_SEASON_COMBIND_PARTNER.csv', 'tokusei':'ALL_SEASON_IDIOSYNCRASY.csv', 'motimono':'ALL_SEASON_ITEM.csv'}
for method in column_a.keys():
    df_master = pd.DataFrame(columns = ['Season', 'Rule', 'Pokemon', column_a[method], f'Rank_{column_a[method]}'])
    for rule in ['Single', 'Double']:
        for season_num in range(1,12,1):
            with open(f'{file_dir}//Season{season_num}_{rule}_master.json', 'r', encoding='utf-8') as json_open:
                data = json.load(json_open)
            df = data_trans(data, method2 = method, column = ['Pokemon', column_a[method], f'Rank_{column_a[method]}'])
            df['Season'] = season_num
            df['Rule'] = rule
            
            df_master = pd.concat([df_master, df], axis = 0)
            
    df_master['Pokemon']  = df_master.apply(Change_Name,axis=1)
    df_master.to_csv(file_names[method], index=False)

53.9 s ± 3.33 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

Technique vaincue et Pokémon vaincu

Tout d'abord, de la technique et du Pokémon qui ont vaincu ce Pokémon.

%%timeit

Seasons = []
Rules = []
column_a = {'waza': 'Technique vaincue','pokemon':'Pokémon vaincu'}
file_names = {'waza':'ALL_SEASON_KNOCKED_SKILL.csv','pokemon':'ALL_SEASON_KNOCKED_BY.csv'}
for method in column_a.keys():
    df_master = pd.DataFrame(columns = ['Season', 'Rule', 'Pokemon', column_a[method], f'Rank_{column_a[method]}'])
    for rule in ['Single', 'Double']:
        for season_num in range(1,12,1):
            with open(f'{file_dir}//Season{season_num}_{rule}_master.json', 'r', encoding='utf-8') as json_open:
                data = json.load(json_open)
            df = data_trans(data,method1='lose', method2 = method, column = ['Pokemon', column_a[method], f'Rank_{column_a[method]}'])
            df['Season'] = season_num
            df['Rule'] = rule
            
            df_master = pd.concat([df_master, df], axis = 0)
            
    df_master['Pokemon']  = df_master.apply(Change_Name,axis=1)
    df_master.to_csv(file_names[method], index=False)

17.6 s ± 1.14 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

Technique vaincue et ennemi vaincu

%%timeit

Seasons = []
Rules = []
column_a = {'waza': 'Technique vaincue','pokemon':'Pokémon vaincu'}
file_names = {'waza':'ALL_SEASON_KNOCKING_SKILL.csv','pokemon':'ALL_SEASON_KNOCKING.csv'}
for method in column_a.keys():
    df_master = pd.DataFrame(columns = ['Season', 'Rule', 'Pokemon', column_a[method], f'Rank_{column_a[method]}'])
    for rule in ['Single', 'Double']:
        for season_num in range(1,12,1):
            with open(f'{file_dir}//Season{season_num}_{rule}_master.json', 'r', encoding='utf-8') as json_open:
                data = json.load(json_open)
            df = data_trans(data,method1='win', method2 = method, column = ['Pokemon', column_a[method], f'Rank_{column_a[method]}'])
            df['Season'] = season_num
            df['Rule'] = rule
            
            df_master = pd.concat([df_master, df], axis = 0)
            
    df_master['Pokemon']  = df_master.apply(Change_Name,axis=1)
    df_master.to_csv(file_names[method], index=False)

15.7 s ± 1.14 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

Visualisation

Maintenant que nous avons sorti les huit fichiers qui correspondent à la liste ci-dessus, explorons le classeur Tableau et affichons-les.

Union les 9 fichiers csv créés précédemment et les combiner avec le fichier dans lequel la valeur de course, etc. est enregistrée. Ce dernier fichier est sorti brusquement, ce qui est nécessaire pour afficher la mini-icône Pokemon sur la carte de dispersion à l'aide de la fonction de forme personnalisée. Je ne vais pas y toucher profondément cette fois car ce n'est pas nécessaire si vous faites simplement un diagramme de dispersion.

image4

Une fois les données lues, il ne vous reste plus qu'à l'installer. Tableau a une excellente opérabilité et est très bon (marketing direct).

Je l'ai téléchargé sur [Tableau Public](https://public.tableau.com/shared/GD57KTRKF?: Display_count = y &: origin = viz_share_link), donc si vous souhaitez voir le produit fini, veuillez le faire.

Veuillez me pardonner que la conception est presque le paramètre par défaut.

Lorsque vous touchez le produit fini, cela ressemble à ceci.

gif2.gif

Diverses fonctions d'action ont été utilisées pour créer un tableau de bord. Veuillez vous référer à ici pour les actions de survol de la souris Tableau.

5. Confirmation de l'objectif

--Traitez les données obtenues à partir de l'API pour obtenir plus de suggestions que la formule n'en donne --Visualisez avec Tableau et rendez les données plus faciles à voir

Cette fois, nous avons réussi à montrer la transition de la série chronologique et de l'environnement de combat simple / double en définissant les indicateurs de l'indice épidémique et du méta-index comme Zakuri et en créant un nuage de points.

On peut dire que les deux objectifs ci-dessus ont été presque atteints.

En revanche, les indicateurs mentionnés ci-dessus présentent les problèmes suivants.

  1. Il y a une différence par rapport au classement officiel du taux de recrutement (exemple: le classement du patch ragon est faible)

  2. Il existe une différence par rapport à la table des niveaux émise par l'utilisateur (exemple: le rang du patch ragon est bas)

  3. Les Pokémon apportant des contributions invisibles sont sous-estimés (si vous ne vaincre pas l'ennemi, le méta-index sera faible, donc le rang du type de support Pokémon a tendance à être bas, Pokémon qui peut lier la sélection de l'adversaire simplement en le tenant N'est pas reflété, etc.)

  4. Un calcul de niveau clair n'est pas possible (cette fois, le clustering non hiérarchique est utilisé, mais il n'est pas possible de spécifier jusqu'au niveau 〇).

Je pense qu'il existe divers autres problèmes tels que. Au fur et à mesure que cet indice s'améliorera à l'avenir, il aurait peut-être été utile de pouvoir visualiser les données de bataille des batailles classées.

~~ Je voudrais le télécharger sur github quand j'en ai envie. ~~

→ Téléchargé (03/11/2020)

À la prochaine.

Postscript

2020/11/03 Github a publié l'intégralité du code.

environnement

  1. Windows10 Home 1903

  2. Python 3.7.6

  3. Pandas 1.0.1

  4. Sklearn 0.23.2

  5. Tableau Desktop 2020.1.20.0427.1803

La source

© 2020 Pokémon © 1995-2020 Nintendo / Creatures Inc./GAME FREAK Inc. Pocket Monsters, Pokemon et Pokémon sont des marques déposées de Nintendo, Creatures et Game Freak.

Recommended Posts

J'ai analysé les données de combat de rang du bouclier d'épée Pokemon et je les ai visualisées sur Tableau
J'ai vectorisé l'accord de la chanson avec word2vec et je l'ai visualisé avec t-SNE
J'ai essayé de récupérer les données de l'ordinateur portable en le démarrant sur Ubuntu
J'ai essayé de récupérer les données de l'ordinateur portable en le démarrant sur Ubuntu
[Python3] Prenez une capture d'écran d'une page Web sur le serveur et recadrez-la davantage
Peut-être ai-je surestimé l'impact de Shell Shock sur CGI
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai analysé les données de combat de rang du bouclier d'épée Pokemon et je les ai visualisées sur Tableau
Observation en virgule fixe de données spécifiques sur le Web en exécutant automatiquement le navigateur Web sur le serveur (Ubuntu16.04) (1) -Installation du navigateur Web-
Visualisez le centre de l'environnement de combat de rang à partir de l'API Pokemon Home
J'ai pris les données Apple Watch dans Google Colaboratory et je les ai analysées
[Python] J'ai analysé le journal d'un homme au cours de sa première année de vie professionnelle et j'ai fait un jugement positif / négatif sur la vie professionnelle.
Mettez à jour les données en les téléchargeant sur s3 d'aws avec une commande, et supprimez les données utilisées (en chemin)
[Mémo personnel] Obtenez des données sur le Web et faites-en un DataFrame
J'ai essayé 200 fois l'échange magique [Pokemon Sword Shield]
Pokemon x Data Science (3) - Réflexion sur la construction de partie du bouclier d'épée Pokemon à partir de l'analyse du réseau Où est le centre du réseau?
J'ai lu et implémenté les variantes de UKR
[Python3] Prenez une capture d'écran d'une page Web sur le serveur et recadrez-la davantage
[SLAYER] J'ai essayé de confirmer l'âme d'acier en visualisant les paroles de slash metal [Word Cloud]
Data Langling PDF sur l'épidémie de grippe par le ministère de la Santé, du Travail et du Bien-être social
[Challenger à la recherche] Le chargement et l'augmentation des données les plus rapides (bloc-notes Kaggle) je pense
Je voulais juste extraire les données de la date et de l'heure souhaitées avec Django
Lisez le fichier csv avec le notebook jupyter et écrivez le graphique l'un sur l'autre
J'ai essayé de faciliter la modification du paramètre du proxy authentifié sur Jupyter
[Bouclier d'épée Pokémon] J'ai essayé de visualiser la base de jugement de l'apprentissage en profondeur en utilisant la classification des trois familles comme exemple
Je n'aime pas être frustré par la sortie de Pokemon Go, j'ai donc créé un script pour détecter la sortie et le tweeter