Essayez d'analyser le mahjong familial en ligne à l'aide de Python (PARTIE 1: Prendre des données)

Aperçu

Récemment, j'aime jouer avec ma famille sur le site de mahjong en ligne Tenhou une fois par semaine pendant environ 2 heures.

Cette fois, j'expliquerai l'analyse des résultats du concours afin que tout le monde dans la famille puisse le voir sur le web.

En tant que processus:

  1. Analyser avec Python
  2. Visualisez avec Dash
  3. Debroy en utilisant Heroku et Github

Fini comme ça ↓ https://drmahjong.herokuapp.com/

drmahjangsc1.png drmahjangsc2.png drmahjangsc3.png

Le code peut être trouvé sur le Github ci-dessous. https://github.com/mottoki/mahjan-score

Prenez des données

Les données Tenho peuvent être extraites de Log. Prenez les données à l'aide d'un module appelé request.

python.py


import requests
import datetime

new_date = datetime.datetime.now().strftime('%Y%m%d')
url = "https://tenhou.net/sc/raw/dat/"+f"sca{new_date}.log.gz"
filename = f"sca{new_date}.log.gz"

# Download gz file from the url
with open(filename, "wb") as f:
    r = requests.get(url)
    f.write(r.content)

Traitement des données avec Python et Pandas

Filtrez les données brutes par nom de joueur et utilisez la division pour extraire les cadres de données avec uniquement le nom et les points du joueur.

new_data.py


import os
import pickle
import pandas as pd

#Nom de joueur
playercol = ['date', 'Mirataro', 'Shinwan', 'ToShiroh', 'yukoron']

#Convertir en trame de données Pandas
df = pd.read_csv(filename, usecols=[0], error_bad_lines=False, header=None)
df[len(df.columns)] = new_date

#Filtrer par nom de joueur
df = df[(df[0].str.contains(playercol[1])) & 
    (df[0].str.contains(playercol[2])) & 
    (df[0].str.contains(playercol[3])) &
    (df[0].str.contains(playercol[4]))]

#Traiter la trame de données
df[['one','two','three','four']] = df[0].str.split('|', 3, expand=True)
df.columns = ['original', 'date', 'room', 'time', 'type', 'name1']
df['date'] = pd.to_datetime(df['date'], format='%Y%m%d')
df[['empty', 'n1', 'n2', 'n3', 'n4']] = df.name1.str.split(" ", n=4, expand=True)
#N'utilisez que des colonnes importantes
df = df[['date', 'n1', 'n2', 'n3', 'n4']]

#Supprimez les crochets clés attachés à la partition et au nom pour créer un bloc de données
new_score = pd.DataFrame(columns=playercol)
k=0
for i, j in df.iterrows():
   dd = j[0]
   new_score.loc[k, 'date'] = dd
   for name in df.columns[1:]:
       s = j[name]
       player = s.split('(')[0]
       score = [p.split(')')[0] for p in s.split('(') if ')' in p][0]
       score = int(float(score.replace('+', '')))
       new_score.loc[k, player] = score
   k += 1

#Appeler les anciennes données de Pickle
current_dir = os.getcwd()
old_score = pd.read_pickle(f"{current_dir}/players_score.pkl")

#Combinez les nouvelles et anciennes données
concat_score = pd.concat([old_score, new_score], ignore_index=True)
concat_score.to_pickle(f"{current_dir}/players_score.pkl")

Visualisez avec Dash

Utilisez une bibliothèque appelée Dash pour visualiser rapidement les données.

Le didacticiel Dash est le plus simple à comprendre. (Référence: Documentation et guide de l'utilisateur Dash)

La partie qui est interceptée dans Dash est la fonction appelée Callback, mais il y a des gens qui l'expliquent en détail comme Utiliser la bibliothèque de visualisation Python Dash 2 See Callback. Veuillez vous y référer.

1. Face avant (ce que vous voyez sur le Web)

Expliquer tout le code serait long, je vais donc expliquer la partie principale à titre d'exemple.

En gros, tout ce que vous voyez dans le premier «app.layout» est ce que vous voyez sur votre site Web.

Si vous entrez style = {'display': 'none'}, vous pouvez masquer les choses que vous ne voulez pas afficher (par exemple, les données que vous utilisez plusieurs fois "valeurs intermédiaires") sur le Web.


#Écrivez le front-end dans ce
app.layout = html.Div([
    #Permettre aux utilisateurs de choisir la date qui sera reflétée dans les données
    html.Div([
        html.H2("DR.Mahjong"),
        dcc.DatePickerRange(
            id='my-date-picker-range',
            min_date_allowed=dt(2020, 3, 1),
            max_date_allowed=dt.today(),
            end_date=dt.today()
        ),
        ], className="mytablestyle"),

    #Données utilisées plusieurs fois:style={'display': 'none'}Rends-le invisible
    html.Div(id='intermediate-value', style={'display': 'none'}),

    #Transition de points (graphique)
    dcc.Graph(id='mygraph'),

    #Points complets (tableau)
    html.Div([
            html.Div(html.P('Total actuel des points')),
            html.Div(id='totalscore'),
        ], className="mytablestyle"),

])

2. Jsonize données avec Callback

Lisez les données avec pandas read_pickle, filtrez par date, jsonize et return.

Cela vous permettra d'utiliser les mêmes données encore et encore dans les graphiques et les tableaux.

@app.callback(Output("intermediate-value", "children"),
    [Input("my-date-picker-range", "start_date"),
    Input("my-date-picker-range", "end_date")])
def update_output(start_date, end_date):
    players = pd.read_pickle('players_score.pkl')
    if start_date is not None:
        start_date = dt.strptime(re.split('T| ', start_date)[0], '%Y-%m-%d')
        players = players.loc[(players['date'] >= start_date)]
    if end_date is not None:
        end_date = dt.strptime(re.split('T| ', end_date)[0], '%Y-%m-%d')
        players = players.loc[(players['date'] <= end_date)]
    return players.to_json(date_format='iso', orient='split')

3. Données de graphique et de tableau avec rappel

Les données jsonisées sont renvoyées à la trame de données Pandas et représentées graphiquement et tabulées.

Le graphique reprend le style Plotly et est représenté par go.Figure ().

La tableisation est représentée par html.Table. Il existe également une bibliothèque appelée dash_table pour les tables, mais cette fois, la table était simple, j'ai donc décidé d'utiliser ce style car je n'en avais pas besoin.

@app.callback([Output('mygraph', 'figure'),
    Output('totalscore', 'children')],
    [Input('intermediate-value', 'children'),
    Input('datatype', 'value')])
def update_fig(jsonified_df, data_type):
    #Restaurez les données Jsonized sur Pandas.
    players = pd.read_json(jsonified_df, orient='split')

    #Graphisme
    fig = go.Figure()
    for i, name in enumerate(players.columns[1:]):
        fig.add_trace(go.Scatter(x=players.date, 
                            y=np.array(players[name]).cumsum(),
                            mode='lines',
                            name=name,
                            line=dict(color=colors[i], width=4)))

    fig.update_layout(plot_bgcolor='whitesmoke',
        title='Transition du total des points',
        legend=dict(
            orientation="h",
            yanchor="bottom",
            y=1.02,
            xanchor="right",
            x=1,)
    )

    #Calculer le total des points
    summed = players.sum()

    #Renvoie des graphiques et des tableaux
    return fig, html.Table([
        html.Thead(
            html.Tr([html.Th(col) for col in summed.index])
            ),
        html.Tbody(
            html.Tr([html.Td(val) for val in summed])
            ),
        ])

Déployer avec Heroku et Github

Enfin, nous déploierons en utilisant Heroku et Github.

Le site Web officiel (Deploying Dash Apps) contient des instructions détaillées sur l'utilisation de Git et Heroku, les méthodes sont donc presque les mêmes.

Le processus ressemble à ceci:

  1. Créez un compte Github

  2. Créez un nouveau référentiel Github

  3. SSH sur Github. (Facultatif, mais plus simple à faire. Voir: Autoriser la connexion ssh à GitHub)

  4. Créez les fichiers requis pour le déploiement (.ignore, Procfile, requirements.txt). Vous avez également besoin de gunicorn, alors installez-le avec pip install gunicorn.

  5. Utilisez la commande Git pour envoyer le fichier ci-dessus et les fichiers de données de ʻapp.pyet deplayers_score.pkl` vers Github.

    git init
    git add .
    git commit -m "message"
    git remote add origin [email protected]:<Nom d'utilisateur>/<Nom du référentiel>
    git push origin master
    
  6. Après avoir confirmé qu'il a été envoyé sur Github, créez un compte Heroku et créez une nouvelle application avec le bouton Nouveau> Créer une nouvelle application (la région n'a pas le Japon, alors sélectionnez États-Unis).

  7. Cliquez sur l'onglet Déployer de l'application créée, définissez Méthode de déploiement sur Github et connectez-vous au référentiel créé dans 2.

  8. Enfin, appuyez sur le bouton noir «Deploy Branch» dans «Manual deploy» pour le déployer sans autorisation.

finalement

Comment était-ce?

Vous pouvez également utiliser cron et le déploiement automatique de Heroku pour automatiser la mise à jour des nouvelles données de Tenho. (Référence: Automatiser le processus de poussée vers Github avec cron)

référence

Recommended Posts

Essayez d'analyser le mahjong familial en ligne à l'aide de Python (PARTIE 1: Prendre des données)
Je veux pouvoir analyser des données avec Python (partie 3)
Je veux pouvoir analyser des données avec Python (partie 4)
Je veux pouvoir analyser des données avec Python (partie 2)
Essayez d'utiliser Excel en utilisant Python (Xlwings)
Essayez d'utiliser django-import-export pour ajouter des données csv à django
Essayez d'utiliser le framework Web Python Tornado Partie 1
Essayez d'utiliser le framework Web Python Tornado Partie 2
Analysons les données Covid-19 (Corona) en utilisant Python [Pour les débutants]
Résumé des outils nécessaires pour analyser les données en Python
(Python) Essayez de développer une application Web en utilisant Django
Nettoyage des données à l'aide de Python
Écrire des données dans KINTONE à l'aide du module de requêtes Python
Essayez d'extraire des mots à haute fréquence en utilisant NLTK (python)
Essayez d'utiliser Tweepy [Python2.7]
[Livre technique] Introduction à l'analyse de données avec Python -1 Chapitre Introduction-
[Introduction à cx_Oracle] (Partie 6) Mappage des types de données DB et Python
Essayez de le faire avec GUI, PyQt en Python
Essayez d'exploiter un fichier Excel en utilisant Python (Pandas / XlsxWriter) ①
Essayez d'exploiter un fichier Excel en utilisant Python (Pandas / XlsxWriter) ②
[Python] Essayez d'analyser le fichier wav (Ver sans plug-in supplémentaire)
[Python] Introduction à la création de graphiques à l'aide de données de virus corona [Pour les débutants]
J'ai essayé d'analyser les données scRNA-seq en utilisant l'analyse des données topologiques (TDA)
[Python] Essayez d'utiliser le canevas de Tkinter
Essayez d'analyser les tendances Twitter
Essayez de comprendre Python soi
Publier sur Twitter en utilisant Python
Commencez à Selenium en utilisant python
Essayez d'utiliser SQLAlchemy + MySQL (partie 1)
Essayez d'utiliser SQLAlchemy + MySQL (partie 2)
Analyse de données à l'aide de pandas python
Résolution de l'introduction d'AOJ aux algorithmes et aux structures de données en Python -Partie1-
Résolution de l'introduction d'AOJ aux algorithmes et aux structures de données en Python -Partie2-
Résolution de l'introduction d'AOJ aux algorithmes et aux structures de données en Python -Partie4-
[Pandas] J'ai essayé d'analyser les données de ventes avec Python [Pour les débutants]
Essayez de vous connecter automatiquement à Netflix en utilisant python sur votre PC
[Python] Analysez les données de match de la ligue Splatoon 2 à l'aide d'un tableau de coefficients de corrélation
Comment mettre à jour une source de données de classeur packagée Tableau à l'aide de Python
Résolution de l'introduction d'AOJ aux algorithmes et aux structures de données en Python -Partie3-
Essayez de résoudre l'itinéraire le plus court avec les données sociales Python + NetworkX +
Essayez d'obtenir des métriques CloudWatch avec la source de données python re: dash
[Python] J'ai essayé d'obtenir diverses informations en utilisant l'API de données YouTube!
Introduction de "scikit-mobility", une bibliothèque qui vous permet d'analyser facilement les données de flux humain avec Python (Partie 1)
Comment installer Python à l'aide d'Anaconda
[Python] Comment FFT des données mp3
Essayez d'utiliser Pillow sur iPython (partie 1)
Application de Python: Nettoyage des données Partie 1: Notation Python
Acquisition de données à l'aide de l'API googlemap de python
Application Python: Traitement des données # 3: Format des données
Essayez d'exploiter Facebook avec Python
Introduction à Python Hands On Partie 1
Essayez d'utiliser Pillow sur iPython (partie 2)
Essayez d'utiliser LevelDB avec Python (plyvel)
Essayez d'utiliser pynag pour configurer Nagios
Essayez de calculer Trace en Python
Essayez de mettre des données dans MongoDB
Essayez de convertir la CLI cloudmonkey en python3 -1