Python新手求助:如何用列表替代数组构建正确格式的两年份统计数据集
解决NBA选秀数据合并的问题
嘿,作为Python新手碰到这种数据拼接的问题太正常了,我来帮你捋清楚怎么搞定!
你的核心问题是:现在的代码把每一年的表格作为单独的二维数组加到table列表里,最后转成DataFrame时,就变成了“每行对应一整年的数据”,而不是你想要的“所有年份的数据上下连续排列”。
最简单的解决方案:用Pandas直接读取HTML表格
篮球参考(Basketball Reference)的页面表格结构非常规范,Pandas自带的read_html函数可以直接帮你抓取表格,完全不用手动解析HTML,省超多事!
import pandas as pd # 初始化空DataFrame用来存放所有年份的数据 final_data = pd.DataFrame() # 遍历1956和1957年(注意range是左闭右开,所以1958刚好到1957年结束) for draft_year in range(1956, 1958): url = f"https://www.basketball-reference.com/draft/NBA_{draft_year}.html#stats::none" # 抓取页面中的第一个表格(就是选秀数据表格) year_table = pd.read_html(url)[0] # 给当前年份的表格加一列年份,方便后续区分数据来源 year_table['Draft Year'] = draft_year # 把当前年份的表格拼接到最终数据里 final_data = pd.concat([final_data, year_table], ignore_index=True) # 保存到CSV文件,去掉自动生成的索引列 final_data.to_csv("nba_draft_stats.csv", index=False)
如果你想坚持用BeautifulSoup解析
如果你还是想自己用BeautifulSoup处理HTML,那我们需要调整数据收集的方式:不要把每一年的表格作为单独元素加到列表,而是按行收集所有年份的数据,最后统一转成DataFrame。
修正后的代码:
import bs4 from bs4 import BeautifulSoup from urllib.request import urlopen import pandas as pd # 初始化一个大列表,用来存放所有行的数据(所有年份的行都会存在这里) all_rows = [] for draft_year in range(1956, 1958): url = f"https://www.basketball-reference.com/draft/NBA_{draft_year}.html#stats::none" soup = BeautifulSoup(urlopen(url), "html.parser") # 获取表头(可选,但加上后CSV会有清晰的列名) header_cells = soup.find("tr", class_="thead").find_all("th") column_names = [cell.text.strip() for cell in header_cells if cell.text.strip()] # 加上年份列的名字 column_names.append("Draft Year") # 遍历所有数据行(页面里的full_table和partial_table类都是有效数据行) data_rows = soup.find_all("tr", class_=["full_table", "partial_table"]) for row in data_rows: # 提取当前行的所有内容:先取<th>里的顺位,再取<td>里的其他数据 row_content = [cell.text.strip() for cell in row.find_all("th") if cell.text.strip()] row_content.extend([cell.text.strip() for cell in row.find_all("td")]) # 把当前年份加到行末尾 row_content.append(str(draft_year)) # 把这一行数据加入大列表 all_rows.append(row_content) # 把大列表转成DataFrame final_data = pd.DataFrame(all_rows, columns=column_names) # 保存到CSV final_data.to_csv("nba_draft_stats.csv", index=False)
为什么原来的代码不对?
你之前的代码里,每次循环把mtable3(单个年份的二维数组)append到table里,最后table是一个包含两个二维数组的列表。当你用pd.DataFrame(table)转换时,Pandas会把每个二维数组当成一行的元素,自然不是你要的上下排列格式。而现在的方法是把所有行数据都放到一个列表里,转成DataFrame就是连续的表格啦!
内容的提问来源于stack exchange,提问作者bagelanta
相关产品推荐
相关产品推荐

