1. ホーム
  2. python

[解決済み] Pythonです。pd.DataFrameの行をループする際に「ValueError: can only convert an array of size 1 to a Python scalar」(サイズ1の配列をPythonのスカラーに変換することしかできません。

2022-02-07 11:20:59

質問

DataFrameの行をループして、複数のスポーツチームの強さの評価を計算したい。

DataFrameのカラム 'home_elo''away_elo' は、関係するチームの試合前の戦力評価(ELOスコア)を含み、試合後の次のホーム/アウェイ戦の行で更新されます(各チームは、ホームゲームとアウェイゲームについて、どの時点でも2つの戦力評価を持ちます)、何をもって update_elo(a,b,c) を返します。

それぞれのコードスニペットは次のようになります。

for index in df.index:

    counter = counter + 1
    # Calculation of post-match ELO scores for home and away teams
    if df.at[index,'updated'] == 2: # Update next match ELO scores if not yet updated but pre-match ELO scores available

        try:
            all_home_fixtures = df.date_rank[df['localteam_id'] == df.at[index,'localteam_id']]
            next_home_fixture = all_home_fixtures[all_home_fixtures > df.at[index,'date_rank']].min()
            next_home_index = df[(df['date_rank'] == next_home_fixture) & (df['localteam_id'] == df.at[index,'localteam_id'])].index.item()
        except ValueError:
            print('ERROR 1 at' + str(index))
            df.at[index,'updated'] = 4

        try:
            all_away_fixtures = df.date_rank[df['visitorteam_id'] == df.at[index,'visitorteam_id']]
            next_away_fixture = all_away_fixtures[all_away_fixtures > df.at[index,'date_rank']].min()
            next_away_index = df[(df['date_rank'] == next_away_fixture) & (df['visitorteam_id'] == df.at[index,'visitorteam_id'])].index.item()
        except ValueError:
            print('ERROR 2 at' + str(index))
            df.at[index,'updated'] = 4

        # print('Current: ' + str(df.at[index,'fixture_id']) + '; Followed by: ' + str(next_home_fixture))
        # print('Current date rank: ' + str(df.at[index,'date']) + ' ' + str(df.at[index,'date_rank']) + '; Next home date rank: ' + str(df.at[next_home_index,'date_rank']) + '; Next away date rank: ' + str(df.at[next_away_index,'date_rank']))

        df.at[next_home_index, 'home_elo'] = update_elo(df.at[index,'home_elo'],df.at[index,'away_elo'],df.at[index,'actual_score'])
        df.at[next_away_index, 'away_elo'] = update_elo(df.at[index,'away_elo'],df.at[index,'home_elo'],1 - df.at[index,'actual_score']) # Swap function inputs for away team


        df.at[next_home_index, 'updated'] = df.at[next_home_index, 'updated'] + 1
        df.at[next_away_index, 'updated'] = df.at[next_away_index, 'updated'] + 1

        df.at[index,'updated'] = 3

このコードは、最初の数行については問題なく動作します。しかし、その後、常に同じ行でエラーが発生します。その行が他の行とどのように違うのかがわからないのに。

  1. を処理しない場合 ValueError のように、エラーメッセージが表示されます。 ValueError: can only convert an array of size 1 to a Python scalar が250行ほどで初めて表示されます。
  2. を処理した場合 ValueError しかし、エラーメッセージは表示されず、全行数の約18%で強度評価の更新が停止してしまいます。

(a)エラーの原因を理解し、(b)どのように対処すればよいか、ご教示いただければ幸いです。

StackOverflowへの投稿はこれが初めてなので、フォーラムの一般的な投稿方法についてまだ十分に理解していないのです。私の投稿について改善できることがあれば教えてください。

ありがとうございました。

解決方法は?

pd.Series.item は、スカラーを返すために、シリーズの中の少なくとも1つの項目を必要とします。もし

df[(df['date_rank'] == next_home_fixture) & (df['localteam_id'] == df.at[index,'localteam_id'])]

が長さ0のSeriesの場合 .index.item() はValueErrorを投げます。