[PYTHON] Visualisation du classement des stagiaires de Produce 101 Japan par grattage

Qu'est-ce que Produce 101 Japan?

PRODUCE 101 JAPAN OFFICIAL SITE Il s'agit de la version japonaise du programme d'audition importé de Corée du Sud, et les résultats du vote pour les stagiaires qui souhaitent faire leurs débuts en tant que chanteur sont annoncés chaque semaine. Au fur et à mesure que la semaine avance, le nombre d'abandons passera à 60e et 35e.

Cette fois, les résultats du classement sont extraits du site officiel par grattage. J'ai essayé de visualiser l'évolution du classement des stagiaires qui ont survécu au dernier classement (9ème semaine au 29 novembre 2019).

Dessin final du produit fini

Certains noms des stagiaires sont cachés. Unknown.png

Flux principal

  1. Grattage
  2. Mise en forme des données
  3. Visualisez le classement

1. Obtenez un classement en grattant

Fonctionnalisé pour que les classements hebdomadaires puissent être collectés individuellement. Utilisez BeautifulSoup pour obtenir des éléments HTML et les convertir en texte. Obtenez sous la forme de "rang, nom, semaine" (seule une partie est affichée). aaa.png


def getWeeklyRank(week):
    import requests
    from bs4 import BeautifulSoup
    import re

    #Obtenez l'URL de la page de classement en formatant avec des nombres
    url = 'https://produce101.jp/rank/?week={}'
    html = requests.get(url.format(week))   
    #Gérez les URL avec Beautiful Soup
    soup = BeautifulSoup(html.text, 'lxml')
    #Obtenir les éléments span et div d'une classe particulière
    span_rank = soup.find_all("span", class_="icon-rank")
    div_name = soup.find_all("div", class_="name")
    
    #Extraire le composant texte de la balise contenant le rang et le nom dans la liste
    rank = []
    for i in range(len(span_rank)):
        rank.append(int(span_rank[i].text))
    name = []
    for i in range(len(div_name)):
        name.append(div_name[i].text)

    #Économisez chaque semaine
    #Créer un nouveau uniquement la première semaine et écrire en mode supplémentaire à partir de la semaine prochaine
    if week == 1:
        f = open('./weeklyRank.txt', 'w')
        for i in range(len(rank)):
            f.write(str(rank[i])+','+str(name[i])+','+str(week)+'\n')
        f.close()
    elif week > 1:
        f = open('./weeklyRank.txt', 'a')
        for i in range(len(rank)):
            f.write(str(rank[i])+','+str(name[i])+','+str(week)+'\n')
        f.close()

Exécutez la fonction chaque semaine et obtenez le classement. (C'est cool de tout obtenir automatiquement, mais cette fois, je vais l'obtenir régulièrement.)

getWeeklyRank(1)
getWeeklyRank(2)
getWeeklyRank(3)
#Aucun classement annoncé dans la 4ème semaine
getWeeklyRank(5)
getWeeklyRank(6)
#Aucun classement annoncé à la 7e semaine
getWeeklyRank(8)
getWeeklyRank(9)

2. Facilitez la création de graphiques en façonnant les données

Supprimez les éléments autres que le nom tels que "* déclin", mettez en forme l'en-tête de colonne comme semaine et entrez le classement. Remplacez le classement des stagiaires qui ont abandonné en cours de route par «x». beforeFormat.png

#Effacez la notation du déclin

f = open('weeklyRank.txt', 'r')
data_lines = f.read()
data_lines = data_lines.replace('* Déclin', '')
f.close()

f = open('weeklyRank.txt', 'w')
f.write(data_lines)
f.close()

Formate les données de classement obtenues à partir de HTML. Il y a des coupures allant jusqu'à la 60e place la 5e semaine et jusqu'à la 35e place la 8e semaine, et comme le nombre de personnes change, nous répondrons individuellement.

def getWeeklyRank_format(data_path):
    import pandas as pd
    df_rank = pd.read_csv(data_path,header=None, names=('rank', 'name', 'week'))
    df = df_rank[['name','week','rank']]
    df_week1 = df_rank[df_rank['week'] == 1]
    df_week5 = df_rank[df_rank['week'] == 5]
    df_week8 = df_rank[df_rank['week'] == 8]
    f = open('./weeklyRank_format.txt', 'w')
    f.write('week')

    #Obtenez un membre de week1
    name_week1 = []
    for e in range(len(df_week1)):
        dfe = df[(df['week'] == 1) & (df['rank'] == e+1)]
        nameArray = dfe['name'].values[0]
        f.write(str(','+nameArray))
        name_week1.append(str(nameArray))
    #Obtenez un membre de week5
    name_week5 = []
    for e in range(len(df_week5)):
        dfe = df[(df['week'] == 5) & (df['rank'] == e+1)]
        nameArray = dfe['name'].values[0]
        name_week5.append(str(nameArray))
    f.write('\n') 
    #Obtenez un membre de week8
    name_week8 = []
    for e in range(len(df_week8)):
        dfe = df[(df['week'] == 8) & (df['rank'] == e+1)]
        nameArray = dfe['name'].values[0]
        name_week8.append(str(nameArray))
    f.write('\n') 
    #Entrez le rang des stagiaires la première semaine comme en-tête de colonne et les rangs suivants comme variables.
    for i in range(1,10):
        if i==1 or i==2 or i==3:
            #Écrivez la semaine dans la colonne 0
            f.write(str(i))
            #Ensuite, obtenez le rang des stagiaires la première semaine
            for j in range(0, len(name_week1)):
                dfi = df[(df['week'] == i) & (df['name'] == name_week1[j])]
                f.write(str(','+str(dfi['rank'].values[0])))
        elif i==4:
            continue
        elif i==5 or i==6:
            #Écrivez la semaine dans la colonne 0
            f.write(str(i))
            #Ensuite, obtenez le rang des stagiaires la première semaine
            for j in range(0, len(name_week1)):
                if name_week1[j] in name_week5:
                    dfk = df[(df['week'] == i) & (df['name'] == name_week1[j])]
                    f.write(str(','+str(dfk['rank'].values[0])))   
                elif name_week1[j] not in name_week5:
                    f.write(',x')
        elif i==7:
            continue
        elif i==8 or i==9:
            #Écrivez la semaine dans la colonne 0
            f.write(str(i))
            #Ensuite, obtenez le rang des stagiaires la première semaine
            for j in range(0, len(name_week1)):
                if name_week1[j] in name_week8:
                    dfk = df[(df['week'] == i) & (df['name'] == name_week1[j])]
                    f.write(str(','+str(dfk['rank'].values[0])))   
                elif name_week1[j] not in name_week8:
                    f.write(',x')            
        f.write('\n') 
    f.close()

Exécutez la fonction.

getWeeklyRank_format('./weeklyRank.txt')

Voyons si cela a fonctionné.

import pandas as pd
df_rank = pd.read_csv('./weeklyRank_format.txt',header=0)
df_rank
df.png

3. Visualisez le classement

Cette fois, j'utiliserai Police téléchargée: JK Gothic L pour écrire en japonais avec un œil sur l'apparence.

#Classement des stagiaires de la 1ère semaine à la 9ème semaine
#Personnalisez la police
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np

#Appliquer la police en spécifiant directement le fichier ttf
import matplotlib.font_manager
fp = matplotlib.font_manager.FontProperties(fname='/Users/[USER NAME]/.matplotlib/fonts/ttf/JKG-L_3.ttf')

#Définir le champ
fig, axs = plt.subplots(figsize=(10,25))
x = df_rank['week']
axs.set_xlim(0.94,9.1)
axs.set_xticks([1, 2, 3, 4, 5, 6, 7, 8, 9])
axs.set_ylim(99, 0.6)

axs2 = axs.twinx()

labels = list(df_rank.columns[1:])[0:]
axs.set_yticks(list(np.arange(1,99)))
axs.set_yticklabels(labels, fontproperties=fp, color='darkslateblue')
axs.set_xticklabels(['1ère semaine', '2ème semaine', '3e semaine','4ème semaine', '5ème semaine', '6ème semaine', '7ème semaine', '8ème semaine', '9ème semaine'], rotation=0, fontsize=14, fontproperties=fp, color='darkslateblue')
axs.spines['top'].set_visible(False)
axs.spines['bottom'].set_visible(False)
axs.spines['right'].set_visible(False)
axs.spines['left'].set_visible(False)
axs.tick_params(left=False)

labels2 = list((np.arange(0,99)))
axs2.set_yticks(list(np.arange(1,99)))
axs2.set_yticklabels(labels2[99:0:-1], fontproperties=fp, color='darkslateblue')
axs2.set_ylim(0,98)
axs2.spines['top'].set_visible(False)
axs2.spines['bottom'].set_visible(False)
axs2.spines['right'].set_visible(False)
axs2.spines['left'].set_visible(False)
axs2.tick_params(right=False)

#Changer la couleur de la ligne de pliage en arc-en-ciel
cmap = plt.get_cmap('rainbow')
for i in range(1, 99,1):
    y = df_rank[df_rank.columns[i]]
    if 'x' in list(y):
        continue
    else:
        axs.plot(x,y,color=cmap(1-i/100),marker='o',markersize=8,linewidth = 3, alpha=0.3)

Cela devrait compléter le graphique. Si vous définissez les conditions, vous pouvez visualiser les stagiaires qui ont grandement amélioré leur classement.

Recommended Posts

Visualisation du classement des stagiaires de Produce 101 Japan par grattage
Visualisation des données par préfecture
Visualisation de la matrice créée par numpy
Obtenez la liste "J'aime" de Qiita en grattant
Analyse des données financières par pandas et leur visualisation (2)
Analyse des données financières par pandas et leur visualisation (1)
Comment visualiser les données par variable explicative et variable objective