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

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

ただいまの
回答率

87.58%

DataFrameを定期的に更新し、情報を蓄積したい。

解決済

回答 2

投稿 編集

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

score 19

プログラムの概要

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

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

分からないこと

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

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

実際のコード

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) # ④の部分

コード全体

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__'





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)

    print(df)


__name__ == '__selfdeck_list__'

selfdeck_list("Scott")
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

以下のようなコードで実行毎に行を追加できます。

import pandas as pd
import os
from datetime import datetime

path = 'ret.csv'
if os.path.isfile(path):
    df = pd.read_csv(path) # 既存ファイルがあれば読み込む
else:
    df = pd.DataFrame({'no':[],'dt':[]}) # なければ雛型を作成

# 'no'列に連番をいれるテスト
no = 1
if len(df) > 0:
    no = df.tail(1).iat[0,0] + 1
    print(no)

# 実行毎に行を追加
df = df.append({'no':no,'dt':datetime.now()},ignore_index=True)

df.to_csv(path,index=False)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/18 21:11 編集

    ありがとうございます。教えていただいた通り修正したところ、定期的に実行毎に行追加できました。
    しかし、重複する行を削除できなくなってしまいました。何か改善策はありますでしょうか?

    修正後のコード↓

    def selfdeck_list(name):

    columns1=["type","my","opponent","result","time"]
    ba = battle_info(name)
    datalist = []


    path = filedic[name]
    if os.path.isfile(path):
    df = pd.read_csv(path) # 既存ファイルがあれば読み込む
    else:
    df = pd.DataFrame(columns=columns1)# なければ雛型を作成


    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)


    df = df.append(datalist,ignore_index=True).drop_duplicates().reset_index(drop=True)
    df.to_csv(path,index=False)


    __name__ == '__selfdeck_list__'

    selfdeck_list("Scott")

    キャンセル

  • 2019/05/18 21:18

    for newnum in range(0,25):以降の処理詳細を把握していないため何とも云えませんが、まずは
    どの行とどの行(既ファイル保存行と?)が重複しているのか?
    その原因は何か?を確認、特定することから進めることがよろしいかと思います。

    キャンセル

  • 2019/05/18 21:33

    恐らく、定期的に実行した際に返ってくる値(datalist)に重複した部分があり、それを処理するdrop_duplicates()がうまく機能していないのかなと思います。

    ありがとうございます。もう少し試してみます。

    キャンセル

0

シリアライズすれば永続化できます。

pandas シリアライズで調べると参考になるサイトがたくさん出てくると思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/18 09:20

    ありがとうございます。検索してみます!

    キャンセル

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

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

関連した質問

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