Python Добавление DataFrame, странная ошибка цикла - PullRequest
0 голосов
/ 29 сентября 2019

Я работаю над поиском статистики в НФЛ, честно говоря, эта деятельность не имеет большого значения.Я потратил кучу времени на отладку, потому что не мог поверить в то, что он делал, либо я схожу с ума, либо в пакете или самом Python есть какая-то ошибка.Вот код, с которым я работаю:

import pandas as pd
from bs4 import BeautifulSoup as bs
import requests
import string
import numpy as np

#get player list
players = pd.DataFrame({"name":[],"url":[],"positions":[],"startYear":[],"endYear":[]})
letters = list(string.ascii_uppercase)
for letter in letters:
    print(letter)
    players_html = requests.get("https://www.pro-football-reference.com/players/"+letter+"/")
    soup = bs(players_html.content,"html.parser")
    for player in soup.find("div",{"id":"div_players"}).find_all("p"):
        temp_row = {}
        temp_row["url"] = "https://www.pro-football-reference.com"+player.find("a")["href"]
        temp_row["name"] = player.text.split("(")[0].strip()
        years = player.text.split(")")[1].strip()
        temp_row["startYear"] = int(years.split("-")[0])
        temp_row["endYear"] = int(years.split("-")[1])
        temp_row["positions"] = player.text.split("(")[1].split(")")[0]
        players = players.append(temp_row,ignore_index=True)
players = players[players.endYear > 2000]
players.reset_index(inplace=True,drop=True)

game_df = pd.DataFrame()
def apply_test(row):
    #print(row)
    url = row['url']
    #print(list(range(int(row['startYear']),int(row['endYear'])+1)))
    for yr in range(int(row['startYear']),int(row['endYear'])+1):
        print(yr)
        content = requests.get(url.split(".htm")[0]+"/gamelog/"+str(yr)).content
        soup = bs(content,'html.parser').find("div",{"id":"all_stats"})
        #overheader
        over_headers = []
        for over in soup.find("thead").find("tr").find_all("th"):
            if("colspan" in over.attrs.keys()):
                for i in range(0,int(over['colspan'])):
                    over_headers = over_headers + [over.text]
            else:
                over_headers = over_headers + [over.text]
        #headers
        headers = []
        for header in soup.find("thead").find_all("tr")[1].find_all("th"):
            headers = headers + [header.text]
        all_headers = [a+"___"+b for a,b in zip(over_headers,headers)]
        #remove first column, it's meaningless
        all_headers = all_headers[1:len(all_headers)]
        for row in soup.find("tbody").find_all("tr"):
            temp_row = {}
            for i,col in enumerate(row.find_all("td")):
                temp_row[all_headers[i]] = col.text
            game_df = game_df.append(temp_row,ignore_index=True)
players.apply(apply_test,axis=1)


Теперь я снова могу понять, что я пытаюсь сделать, но здесь, похоже, есть проблема более высокого уровня.startYear и endYear в цикле for - это 2013 и 2014, поэтому в цикле следует установить переменную yr на 2013, а затем на 2014. Но когда вы посмотрите на то, что выводится из-за print(yr), вы поймете, что он печатает 2013 дважды.Но если вы просто закомментируете строку game_df = game_df.append(temp_row,ignore_index=True), распечатки yr будут правильными.Вскоре после первых двух строк есть ошибка, но это ожидаемо, и одну мне удобно отлаживать.Но тот факт, что добавление к глобальному фрейму данных приводит к тому, что цикл for ведет себя по-другому, прямо сейчас поражает воображение.Может кто-нибудь помочь с этим?

Спасибо.

1 Ответ

1 голос
/ 29 сентября 2019

Я не совсем понимаю, какова общая цель, но я отмечаю две вещи:

  1. Вам либо нужно, чтобы локальный game_df был объявлен как global game_df перед game_df = game_df.append(temp_row,ignore_index=True) или, что еще лучше, передается как arg в сигнатуре def, хотя вам необходимо изменить это: players.apply(apply_test,axis=1) соответственно.

  2. Вам необходимо обработать случаи, когда возвращаемый поиск отсутствует, например, с помощьюsoup.find("thead").find_all("tr")[1].find_all("th") для страницы https://www.pro -football-reference.com / Players / A / AaitIs00 / gamelog / 2014 .Возможно, вставьте try except блоков с соответствующими значениями по умолчанию.

...