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

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

新規登録して質問してみよう
ただいま回答率
86.12%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

解決済

エラーの解決法を教えてください IndexError: single positional indexer is out-of-bounds

mmtt
mmtt

総合スコア22

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1回答

0グッド

1クリップ

33294閲覧

投稿2019/06/04 13:45

## わからないこと
表題の通りエラーが発生していますが、解決法が分かりません。

##プログラムの概要
①あるサイトからスクレイピング→②pandasのデータフレームに収納→③データを用いて画像を結合→④Twitterに投稿
というプログラムになっており、今回エラーが発生したのはおそらく③の部分だと思います。

エラー内容

C:\Users\maoto>C:\Users\maoto\Desktop\python_lesson\CRL\twitterbot.py Traceback (most recent call last): File "C:\Users\maoto\Desktop\python_lesson\CRL\twitterbot.py", line 2, in <module> import crl_image File "C:\Users\maoto\Desktop\python_lesson\CRL\crl_image.py", line 84, in <module> a = imgdic[df.iloc[rank,0][0]] File "C:\Users\maoto\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\indexing.py", line 1494, in __getitem__ return self._getitem_tuple(key) File "C:\Users\maoto\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\indexing.py", line 2143, in _getitem_tuple self._has_valid_tuple(tup) File "C:\Users\maoto\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\indexing.py", line 223, in _has_valid_tuple self._validate_key(k, i) File "C:\Users\maoto\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\indexing.py", line 2070, in _validate_key self._validate_integer(key, axis) File "C:\Users\maoto\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\indexing.py", line 2139, in _validate_integer raise IndexError("single positional indexer is out-of-bounds") IndexError: single positional indexer is out-of-bounds

自分なりにやってみたこと

エラー内容を読む限り、<crl_image>というファイルの84行目のa = imgdic[df.iloc[rank,0][0]]という箇所に不具合があるようなので、googlecoraboratoryを用いて
print(a)をしてみたり、print(df)を行ってみたりしましたが、何事もなく正常な値が表示されました。

##実際のコード全体
まず、<twitterbot.py>というファイル名です。

<twitterbot.py> import tweepy import crl_image from bs4 import BeautifulSoup import requests import pandas as pd import numpy as np #ファイル名の辞書作成 card=["Baby Dragon","Minions",,"Heal"] # 中略 img = {'Baby Dragon': 'baby_dragon.png', 'Goblin Gang': 'goblin_gang.png', 'Minions': 'minion.png"' 'Heal': 'heal.png'} #中略 # dfを作成し、データを収集し格納 list = [] list1 = [] list2 = [] list3 = [] list4 = [] list5 = [] df = pd.DataFrame() url = "https://royaleapi.com/decks/popular?time=1d&sort=win&size=30&players=PvP&min_trophies=0&max_trophies=10000&mode=detail&type=TopLadder&&&global_exclude=false" # トッププレーヤーマルチ勝率 html_doc = requests.get(url).text soup=BeautifulSoup(html_doc,"html.parser") tags = soup.find_all("img") for tag in tags: a = tag.get("alt") if a == None: pass else: list.append(a) list1 = [list[idx:idx + 8] for idx in range(0,len(list), 8)] df["card"]=list1 tags2 = soup.find_all("td",{"class":"right aligned strong"}) for tag2 in tags2: b = tag2.text list2.append(b) df["winrate"] = list2 tags3 = soup.find_all("div",{"class":"ui black inverted label margin0"}) for tag3 in tags3: c = tag3.text[1:5] list3.append(c) df["userate"] = list3 tags4 = soup.find_all("div",{"class":"header item mobile-hide tablet-hide"}) for tag4 in tags4: d = tag4.text.strip("\n") list4.append(d) df["deckname"] = list4 tags5 = soup.find_all("a",{"class":"ui blue icon circular button button_popup"}) for tag5 in tags5: e = tag5.get("href") list5.append(e) df["link"] = list5 CK = "" #(API key) CS = "" #(API secret key) AT = "" #(Access token) AS = "" #(Access token secret) # Twitterオブジェクトの生成 auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) api = tweepy.API(auth) # ツイート #api.update_status("自動投稿テスト") #画像付きツイート winrate = df.iloc[0,1] userate = df.iloc[0,2] deckname = df.iloc[0,3] link = df.iloc[0,4] api.update_with_media(status = '【マルチ勝率1位デッキ】\n \n ■Deck:%s \n ■Win rate:%s \n ■Use rate:%s \n ■Link:%s ' % ( deckname,winrate,userate,link ), filename = 'test.png')#画像のファイル名いれる

次に、<crl_image>というファイルです。

from PIL import Image # ライブラリの読み込み from bs4 import BeautifulSoup import requests import pandas as pd import numpy as np #ファイル名の辞書作成 card=["Baby Dragon","Minions","Balloon","Goblin Barrel", "Miner","Ice Wizard","Mega Minion", "Goblin Gang", "Bats","Barbarians", "Lava Hound", "Giant","Guards", "Dark Prince", "Electro Wizard","Bandit", "Battle Ram","Executioner","Hog Rider", "Ice Spirit", "Golem", "Fire Spirit","Three Musketeers","Royal Giant","P.E.K.K.A","Mega Knight","Elite Barbarians","Giant Skeleton","Goblin Giant","Sparky","Ice Gorem", "Minion Horde","Rascals","Witch","Prince","Bowler","Cannon Cart","Electro Dragon","Ram Rider","Royal Hogs","Hunter","Royal Recruits", "Lumberjack","Inferno Dragon","Night Witch","Magic Archer","Valkyrie","Musketeer","Mini P.E.K.K.A","Zappies","Flying Machine","Knight","Archers", "Bomber","Skeleton Barrel","Skeleton Army","Wall Breakers","Princess","Royal Ghost","Dart Goblin","Goblins","Spear Goblins","Skeletons","Bomb Tower", "Cannon","Inferno Tower","Mortar","Tesla","X-Bow","Barbarian Hut","Elixir Collector","Furnace","Goblin Hut","Tombstone","Goblin Cage","Arrows", "Barbarian Barrel","Fireball","Rocket", "Giant Snowball","Lightning","Poison","The Log","Tornado","Zap","Clone","Earthquake","Graveyard","Freeze", "Rage","Mirror","Heal"] imgdic = {'Baby Dragon': 'baby_dragon.png', ' Heal': 'heal.png'}# 中略 # dfを作成し、データを収集し格納 list = [] list1 = [] list2 = [] list3 = [] list4 = [] list5 = [] df = pd.DataFrame() url="https://royaleapi.com/decks/popular?time=1d&sort=win&size=30&players=PvP&min_trophies=6300&max_trophies=10000&mode=detail&type=Ladder&&&global_exclude=false" # トッププレーヤーマルチ勝率 html_doc = requests.get(url).text soup=BeautifulSoup(html_doc,"html.parser") #print(soup) tags = soup.find_all("img") for tag in tags: a = tag.get("alt") if a == None: pass else: list.append(a) list1 = [list[idx:idx + 8] for idx in range(0,len(list), 8)] df["card"]=list1 tags2 = soup.find_all("td",{"class":"right aligned strong"}) for tag2 in tags2: b = tag2.text list2.append(b) df["winrate"] = list2 tags3 = soup.find_all("div",{"class":"ui black inverted label margin0"}) for tag3 in tags3: c = tag3.text[1:5] list3.append(c) df["userate"] = list3 tags4 = soup.find_all("div",{"class":"header item mobile-hide tablet-hide"}) for tag4 in tags4: d = tag4.text.strip("\n") list4.append(d) df["deckname"] = list4 tags5 = soup.find_all("a",{"class":"ui blue icon circular button button_popup"}) for tag5 in tags5: e = tag5.get("href") list5.append(e) df["link"] = list5 rank = 0  # 上から何番目のデッキか a = imgdic[df.iloc[rank,0][0]] b = imgdic[df.iloc[rank,0][1]] c = imgdic[df.iloc[rank,0][2]] d = imgdic[df.iloc[rank,0][3]] e = imgdic[df.iloc[rank,0][4]] f = imgdic[df.iloc[rank,0][5]] g = imgdic[df.iloc[rank,0][6]] h = imgdic[df.iloc[rank,0][7]] # 写真を結合し出力 im1 = Image.open(a) im2 = Image.open(b) im3 = Image.open(c) im4 = Image.open(d) im5 = Image.open(e) im6 = Image.open(f) im7 = Image.open(g) im8 = Image.open(h) def get_concat_42(im1,im2,im3,im4,im5,im6,im7,im8): dst = Image.new('RGB', (im1.width + im2.width + im3.width + im4.width+6, im1.height + im5.height+2),"white") dst.paste(im1,(0,0)) dst.paste(im2,(im1.width+2,0)) dst.paste(im3,(im1.width+im2.width+4,0)) dst.paste(im4,(im1.width+im2.width+im3.width+6,0)) dst.paste(im5,(0,im1.height+2)) dst.paste(im6,(im5.width+2,im1.height+2)) dst.paste(im7,(im5.width+im6.width+4,im1.height+2)) dst.paste(im8,(im5.width+im6.width+im7.width+6,im1.height+2)) return dst get_concat_42(im1,im2,im3,im4,im5,im6,im7,im8).save('test.png')

以下のような質問にはグッドを送りましょう

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

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

気になる質問をクリップする

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

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

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

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

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

境界の外をインデクシングしようとしているということで、想定より大きな値がいずれかのインデックスの数字に入ってしまっているか、df, imgdicのいずれかが想定より小さいのでしょう(コードを見る限り、imgdicは辞書型でしょうか。その場合はdfだけが問題です)。

とりあえず3行に分けて書いてみるといいでしょう。

python

1# a = imgdic[df.iloc[rank,0][0]] 2tmp1 = df.iloc[rank,0] 3tmp2 = tmp1[0] 4a = imgdic[tmp2]

これで正確なエラー箇所がわかりますので、途中の値のtmp1, tmp2をチェックしてみてください。

投稿2019/06/04 14:05

hayataka2049

総合スコア30892

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

このような回答には修正を依頼しましょう。

回答へのコメント

mmtt

2019/06/04 14:32

ありがとうございます。アドバイスをいただいた通りに実行すると、tmp1=...の列に同様のエラーが出ました!
hayataka2049

2019/06/04 14:46 編集

その上の行にprint(df.to_csv())を入れた場合の出力結果を教えてください。
hayataka2049

2019/06/04 15:01

ご自身で確認されてもいいのですが、空のdfになっている公算が大きいです。
mmtt

2019/06/04 15:25 編集

その通りでした。列名のみ入っており、肝心のデータが空でした。 これ以前のスクレイピングでミスってるようです。 些細なミスでした。すみません。 おかげさまで原因がわかりました。ありがとうございます!
hayataka2049

2019/06/04 15:23

基本的にご自身でデバッグしていただくしかないのですが、まずは取ろうとしているURLをブラウザから開いても Found decks: 0 で何も出てこないところからなんとかするべきではないでしょうか。

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

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。