質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.77%

【python】実行時間を早くできる箇所を教えてください。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 350

mmtt

score 18

解決したいこと

初めてちゃんとしたコードを書いたのですが、実行に5分もかかることがあり、書き方次第でもっと早くできるところがあるんじゃないかと思い質問させていただきました。よろしくお願いします。

特に遅い部分

def selfdeck_list(name,newnum):
    #decktype = battle_info(name)[0]["type"]
    #cardsname = battle_info(name)[0]["team"][0]["cards"][1]["name"]

    内包表記バージョン?
    decklist = [ battle_info(name)[decknum]["team"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
    decktype = [ battle_info(name)[decknum]["type"] for decknum in range(0,25)]"""

    return decktype[int(newnum)]
    return decklist[int(newnum*8):int(newnum*8+8)]

selfdeck_list("Scott",0)

プログラムの概要

クラッシュロワイヤルというゲームのAPIを受け取り、選手の情報や対戦デッキをpandasのデータフレームに収集するというプログラムです。コードの横にコメント形式でもう少し詳細に書いています。

実際のコード全体

#クラロワAPIからプロ選手の情報を取得するプログラム
import time
import json
import requests
import pandas as pd
import numpy as np

access_key = "ここでは省略"

URL = 'https://api.clashroyale.com/v1'

#選手名とパスを結合する辞書を作成
dic={"みかん坊や":"%232VYJYJ09","天GOD":"%232G0QUGLU","kota":"%23889VQ8JP","RAD":"%238QRCJQ9Y","ライキジョーンズ":"%2398Q8LPQ9",
    "Jack":"%23YRVL9U98","きたっしゃん":"%23P8RLYOV9","だに":"%238LJVVGJP","けんつめし":"%23PQRR0CG9",
    "Rorapolon":"%239JPRJ9R","焼き鳥":"%232Y8GL0V2","ユイヒイロ":"%23R2GRQPCJ","Blossom":"%238Q20LRC8Y","kk19212":"%23RU2CC2LG",
    "れいや":"%232LRVG0C8","HANE×HANE":"%238Y088VU8U","Lewis":"%238Q020U0U","ピラメキ":"%232YGQGY92V","天ぷら":"%238Q2V2CGR","Scott":"%232Q98GVP9V"}

# 選手名を含むリストを作成
list= ["みかん坊や","天GOD","kota","RAD","ライキジョーンズ",
    "Jack","きたっしゃん","だに","けんつめし",
    "Rorapolon","焼き鳥","ユイヒイロ","Blossom","kk19212",
    "れいや","HANE×HANE","Lewis","ピラメキ","天ぷら","Scott"]

# 選手の基本情報を取得
def general_info(name):
    target_api = URL + "/players/"
    playerTag = dic[name]
    url = target_api+playerTag
    headers = {
        "content-type": "application/json; charset=utf-8",
        "cache-control": "max-age=60",
        "authorization": "Bearer  %s" % access_key}
    r = requests.get(url,headers=headers)
    data = r.json()
    return data

__name__ == '__general_info__'


# 選手の対戦情報を取得
def battle_info(name):
    target_api = URL + "/players/"
    playerTag = dic[name]
    url = target_api+playerTag+"/battlelog"
    headers = {
        "content-type": "application/json; charset=utf-8",
        "cache-control": "max-age=60",
        "authorization": "Bearer  %s" % access_key}
    r = requests.get(url,headers=headers)
    data = r.json()
    return data

__name__ == '__battle_info__'


# 自分のデッキリストを作成(変数は選手名と何番目のデッキか))
def selfdeck_list(name,newnum):
    #decktype = battle_info(name)[0]["type"]
    #cardsname = battle_info(name)[0]["team"][0]["cards"][1]["name"]

    # 普通の書き方バージョン
    decklist = []

    for decknum in range(0,25):
        decktype = battle_info(name)[decknum]["type"]

        for numindeck in range(0,8):
            cardsname = battle_info(name)[decknum]["team"][0]["cards"][numindeck]["name"]
            decklist.append(cardsname)

    """内包表記バージョン?
    decklist = [ battle_info(name)[decknum]["team"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
    decktype = [ battle_info(name)[decknum]["type"] for decknum in range(0,25)]"""

    return decktype[int(newnum)]
    return decklist[int(newnum*8):int(newnum*8+8)]


selfdeck_list("Scott",0)


# 対戦相手のデッキリストを作成(変数は選手名と何番目のデッキか)
def opponentdeck_list(name, newnum):
    #decktype = battle_info(name)[0]["type"]
    #cardsname = battle_info(name)[0]["team"][0]["cards"][1]["name"]
    # 1つ目の[]は何試合目か、3つ目は8個の中の何番目

    """ 普通バージョン
    decklist = []

    for decknum in range(0,25):
        decktype = battle_info(name)[decknum]["type"]

        for numindeck in range(0,8):
            cardsname = battle_info(name)[decknum]["opponent"][0]["cards"][numindeck]["name"]
            decklist.append(cardsname)"""

    #内包表記バージョン?

    decklist = [ battle_info(name)[decknum]["opponent"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
    decktype = [ battle_info(name)[decknum]["type"] for decknum in range(0,25)]

    return [decktype[int(newnum)], decklist[int(newnum*8):int(newnum*8+8)]]



#2. デッキのdateframe作成
"""
columns1 = ["対戦種類","自デッキ","敵デッキ","勝敗"]

for number in range(0,25):
    player = "Scott"
    datas = selfdeck_list(player,number),opponentdeck_list(player,number)

deckdata = pd.DateFrame(data=datas,index=number,columns=columns1 )

print(deckdata)
"""


#3. datesetの中に入れ、DateFrameを作成
"""
columns2 = ["クラン","タグ","現在トロ","最多トロ","チャレンジ名","デッキ"]

for player in list:
    dataset = general_info(player)["tag"],dic[player],general_info(player)["trophies"],general_info(player)["bestTrophies"],battle_info(player,0)

generaldata = pd.DateFrame(data=dateset,index=list,columns=columns2)
print(generaldata)
"""
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mather

    2019/05/15 11:18

    せめて何をするコードなのか具体的に説明を添えてください。
    また、ベンチマークツールで気になる部分の速度を調べてボトルネックを探してみてください。

    キャンセル

  • can110

    2019/05/15 11:28

    具体的にコード上のどの部分で時間がかかっているかを追記ください。

    キャンセル

  • mmtt

    2019/05/15 11:50

    すみません。追記しました。

    キャンセル

回答 2

checkベストアンサー

0

何度も同じデータが生成されているようですね。

  • return を2回書いてますが2回目は絶対に実行されません
  • YouheiSakuraiさんの回答にもあるように battle_info(name) は一度呼び出したら結果を変数に入れて使いましょう。
  • decktype 等はそのまま配列で返し、出来上がったリストのどの番号を使うかは関数外で指定しましょう。
def selfdeck_list(name):
    battle = battle_info(name)

    内包表記バージョン?
    decklist = [ battle[decknum]["team"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
    decktype = [ battle[decknum]["type"] for decknum in range(0,25)]

    return (decklist, decktype)

decklist, decktype = selfdeck_list("Scott")
decktype[0]

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

battle_infoを呼び出す回数が多いのが原因だと思います。battle_info(name)の戻り値は変数に格納して使い回すと早くなると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る