ろじらぼ(Roji-Lab)

毎日ダラダラゆらゆらと過ごす大学生のめんどくさがりなブログ。

アプリランキングを作ろう~ランキングリスト作成編~

こんにちは!
Roji(ろじ)です!

今回は、アプリランキングの続きで、
抽出したデータにポイントを割り振り、
ソートするところまでやってきます。

この記事では、僕が開発した流れを説明します。
プログラムの詳しい解説等は行いません。
ご了承ください。

【概要】

ランキング用のデータは、
「アプリタイトル、ポイント、画像番号」
のリストで扱っていこうと思います。

CSVファイルに保存したタイトルを、
重複なしで、リストに格納し、
対応するアイコン画像の番号を割り振ります。

リストが完成したら、
ポイントの大きい順にソートして完成です。

【開発】

まず、CSVに保存したアプリタイトルをリストに格納します。

import csv

path = 'CSVファイルを保存したパス'
app_list = []
title_list = []

with open(path + 'AppTitle.csv', encoding='utf_8_sig') as f:
    reader = csv.reader(f)
    for i in csv.reader(f):
        app_list.append(i)

for i in app_list:
    for j in i:
        title_list.append(j.replace('\n', ''))

これで、CSVファイルからリストを生成できます。

「app_list」は、CSVファイルから直接読み込んだアプリタイトル用のリスト、
「title_list」は、「app_list」を成形したデータを格納するためのリスト
として、使用しています。

with open(path + 'AppTitle.csv', encoding='utf_8_sig') as f:
    reader = csv.reader(f)
    for i in csv.reader(f):
        app_list.append(i)

ここは、前回の書き込みの逆です。
指定したパスのCSVファイルを読み込んでます。
ファイル内のすべてのデータを「app_list」に格納しています。

for i in app_list:
    for j in i:
        title_list.append(j.replace('\n', ''))

データをそのまま格納した「app_list」には、
改行コードが付いていたりするので、
ここで改行コードを外し、1次元リストに成形しています。


次に、ランキング用のリストを作っていきます。
リストの中身は、
「アプリタイトル、ポイント、画像番号」
にします。

rank_list = []
count = 0

for i in title_list:
    f = False
    for j in rank_list:
        if i == j[0]:
            j[1] = j[1] + 10 - count % 10
            f = True
            break
    if not(f):
        rank_list.append([i, 10 - count % 10, count])
    
    count += 1

これで、リストに
「アプリタイトル、ポイント、画像番号」
の順にリストを生成できます。

rank_list = []
count = 0

ここでは、ランキング格納用に「rank_list」を作り、
画像番号と関連付ける「count」を初期化しています。

今回のプログラムでは、
イコン画像は「Image0」「Image1」...
と、保存されているので、画像のファイル名に記載されている番号と、
CSVファイルのタイトルの順番が同じになっています。
これを利用して、アプリタイトルとアイコン画像を紐づける作戦です。

f = False

for j in rank_list:
    if i == j[0]:
        j[1] = j[1] + 10 - count % 10
        f = True
        break

最初の「f」は重複フラグを意味しています。
アプリタイトルの重複を確認するために用意しています。

ここのループは、すでに生成されたランキング用のリストの中に、
重複タイトルがあるかどうかを確認しています。
このときの「i」には、アプリタイトルリストの中のタイトルが1つ入っています。
そのタイトルと、ランキングリストのタイトルの部分と比較し、
同じタイトルがあった場合、ポイントを加算します。

ポイントは、1位が10ポイント、2位が9ポイント...となるようにしています。
重複タイトルがあった場合、フラグを建てて、新規のタイトルでないことを示します。

if not(f):
    rank_list.append([i, 10 - count % 10, count])

ループを抜けた後、
もし、重複フラグが建っていない場合、新規のタイトルということになるので、
ランキングリストに追加します。


ランキング用のリストが生成できたので、
そのリストをポイントでソートします。

import pandas as pd

df = pd.DataFrame(data=rank_list, columns=["Title", "Points", "Image"])
df = df.sort_values("Points", ascending=False)

今回、ソートは「pandas」を利用します。
「Points」でソートします。

これで、ソートが完了しました。


ソートしたリストを整えます。

list = df.values
re_list = [[0 for in range(10)] for j in range(2)]

for j in range(10):
    re_list[0][j] = list[j][0]
    re_list[1][j] = list[j][2]

これで、リストの成形が完了しました。


最後に、完成したリストをCSVファイルとして書き出します。

with open(path + "RankingData.csv", "w", newline="", encoding='utf_8_sig') as f:
    writer = csv.writer(f)
    writer.writerows('ランキングリスト')

CSVファイルへの出力は、サイトからデータを抽出したときと同じです。
これで、ランキングリストを出力できました。


今回目標としていたことは完了できました。

次回は、ランキングを表示するところまでいきます。

以上!


【ソース】

import csv
import pandas as pd

def MakeRanking():
    path = 'CSVファイルを保存したパス'
    app_list = []
    title_list = []

    with open(path + 'AppTitle.csv', encoding='utf_8_sig') as f:
        reader = csv.reader(f)
        for i in csv.reader(f):
            app_list.append(i)

    for i in app_list:
        for j in i:
            title_list.append(j.replace('\n', ''))

    rank_list = []
    count = 0

    for i in title_list:
        f = False
        for j in rank_list:
            if i == j[0]:
                j[1] = j[1] + 10 - count % 10
                f = True
                break
        if not(f):
            rank_list.append([i, 10 - count % 10, count])
    
        count += 1

    df = pd.DataFrame(data=rank_list, columns=["Title", "Points", "Image"])
    df = df.sort_values("Points", ascending=False)

    list = df.values
    re_list = [[0 for in range(10)] for j in range(2)]

    for j in range(10):
        re_list[0][j] = list[j][0]
        re_list[1][j] = list[j][2]

    with open(path + "RankingData.csv", "w", newline="", encoding='utf_8_sig') as f:
        writer = csv.writer(f)