

### プログラムの概要

スマホゲームのAPIを用いて、対戦成績に関するデータを収集し、dataframeに入れます。  
※ここでは、定期的に自動でプログラムを実行する部分は未設計です。

具体的には  
①空のデータフレームを作る  
②必要な情報を取得する  
③②を用いてSeriesにまとめる  
④③を空のフレームに追加  
を行おうとしています。

### 分からないこと

関数を定期的に実行し、DateFrameにデータを蓄積するコードの書き方。  
特に、1度目実行したのち一定時間後再度実行した際に、またデータフレームが空の状態になってしまっているため、データが蓄積できていません。

※コードの書き方にエラーがでているわけではありません。

### 実際のコード

[code]

    def selfdeck_list(name):
    
        columns1=["type","my","opponent","result","time"]　#　①の部分
        df = pd.DataFrame(columns=columns1)
    
        ba = battle_info(name)　# ここから②の部分
        datalist = []
        for newnum in range(0,25):
    
            mydecklist = [ ba[decknum]["team"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
            opodecklist= [ ba[decknum]["opponent"][0]["cards"][numindeck]["name"] for decknum in range(0,25) for numindeck in range(0,8) ]
            decktype = [ ba[decknum]["type"] for decknum in range(0,25)]
            mycrowns = [ ba[decknum]["team"][0]["crowns"] for decknum in range(0,25)]
            opocrowns= [ ba[decknum]["opponent"][0]["crowns"] for decknum in range(0,25)]
            time = [ ba[decknum]["battleTime"] for decknum in range(0,25)]
    
            a = decktype[int(newnum)]
            b = tuple(mydecklist[int(newnum*8):int(newnum*8+8)])
            c = tuple(opodecklist[int(newnum*8):int(newnum*8+8)])
            if mycrowns[int(newnum)] > opocrowns[int(newnum)]:
                winorlose = "win"
            elif mycrowns[int(newnum)] < opocrowns[int(newnum)]:
                winorlose = "lose"
            else:
                winorlose = "draw"
            d = winorlose
            e = time[int(newnum)][:15]
            data = [a,b,c,d,e]
            datalist.append(data)
            record = pd.Series(datalist)　# ③の部分
            df = df.append(record, ignore_index=True)　# ④の部分
    
    
    
[/code]

### コード全体

[code]

    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 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__'
    
    
    
[/code]


CC BY-SA 4.0
2019-05-17T13:06:45.357
55062
2019-05-19T04:26:31.353
2019-05-17T20:41:59.260
3605
34254
question
python pandas
DataFrameを定期的に更新し、情報を蓄積したい。


> 関数を定期的に実行し、DateFrameにデータを蓄積するコードの書き方。  
>  特に、1度目実行したのち一定時間後再度実行した際に、またデータフレームが空の状態になってしまっているため、データが蓄積できていません。

色々省略しますが、以下のようなコードで実現できると思います。

[code]

    import pandas as pd
    
    class TestClass:
    
        def __init__(self):
            self.__df = pd.DataFrame([])
    
        def battle_info(self, name):
    
            # 省略
    
            return data
    
        def selfdeck_list(self, name):
            ba = self.battle_info(name)
    
            # 省略
    
            record = pd.Series(datalist)
            self.__df = self.__df.append(record, ignore_index=True)
    
        def polling(self):
            while True:
                # 5秒毎に関数を実行
                time.sleep(5.0)
                self.selfdeck_list("abc")
    
    if __name__ == '__main__':
        cls = TestClass()
        cls.polling()
    
[/code]

もしselfdeck_listを任意のタイミングで、任意の引数を渡して呼び出したい場合は、  
呼び出し先でcls = TestClass()を生成し、cls.selfdeck_list()を呼んでやれば良いです。


CC BY-SA 4.0
2019-05-19T03:45:15.230
55082
2019-05-19T04:26:31.353
2019-05-19T04:26:31.353
3060
27663
55062
answer