Python Pandas:将多行两列数据转置为单行并自定义表头
足球赛事数据爬取与DataFrame格式转换问题
问题描述
我是Python新手,爬取betsapi.com上的英超赛事数据后,得到如下格式的DataFrame:
0 1 2 0 Brighton NaN Man City 1 1 Goals 1 2 5 Corners 1 3 3 Corners (Half) 0 4 2 Yellow Card 1 5 0 Yellow/Red Card 0 6 0 Red Card 0 7 6 Throw-ins 11 8 2 Offsides 0 9 11 Free kicks 18 10 7 Goal kicks 5
我需要把第0行以外的所有行转置合并到第0行,得到这种单行格式:
0 HomeTeam AwayTeam HG AG... 0 Brighton Man City 1 1 5 1 3 0 2 1 0 0 0 0 6 11
试过melt、转置等方法都没解决,已知表头需要手动命名,想知道怎么把每行的主队、客队数据依次转置到第0行。
另外,爬取代码还遇到两个问题:
- 用别人的代码时提示
'axis = 1'不存在 - 简化后的爬取代码出现str/int类型报错,代码如下:
import requests liga_url = "https://betsapi.com/r/6557350/Brighton-vs-Man-City" data = requests.get(liga_url) from bs4 import BeautifulSoup import pandas as pd matches = pd.read_html(data.text) matches = matches[0] # 仅保留第一部分数据,其余重复或无关,仅缺少裁判姓名 matches
解决方案
一、DataFrame格式转换
直接提取数据拼接就能实现需求,步骤如下:
- 先提取主队和客队名称:
home_team = matches.iloc[0, 0] away_team = matches.iloc[0, 2]
- 提取第1行及之后的主队、客队统计数据,把二维数组展平成一维列表:
stats_data = matches.iloc[1:, [0, 2]].values.flatten().tolist()
- 组合成新的DataFrame,手动设置表头:
# 构造表头:主队、客队 + 各项统计的主客字段(比如HG代表主队进球,AG代表客队进球) headers = ['HomeTeam', 'AwayTeam'] for stat_name in matches.iloc[1:, 1].tolist(): # 这里用统计名称前两位缩写,你可以根据需求自定义命名 headers.append(f'H{stat_name[:2]}') headers.append(f'A{stat_name[:2]}') # 生成单行数据的DataFrame new_df = pd.DataFrame([[home_team, away_team] + stats_data], columns=headers) print(new_df)
运行后就能得到你要的单行格式,表头命名规则可以根据自己的需求调整。
二、爬取代码报错排查
1. 'axis = 1'不存在报错
这个错误大概率是参数拼写或方法误用导致的:
- 检查代码里写
axis = 1的地方,正确写法是axis=1(不要加空格) - 如果是调用
drop、sum这类支持axis参数的方法,确认方法是否真的支持该参数(比如某些旧版pandas函数可能有差异) - 如果是自定义函数或第三方库方法,查看文档确认参数是否正确。
2. str/int类型报错
pd.read_html返回的DataFrame里,部分列可能混合了字符串和数值类型,导致后续操作报错。可以这么处理:
- 先查看各列数据类型:
print(matches.dtypes),定位到混合类型的列 - 对需要数值类型的列进行强制转换,忽略转换失败的内容:
# 转换第0列和第2列为数值类型 matches[0] = pd.to_numeric(matches[0], errors='coerce') matches[2] = pd.to_numeric(matches[2], errors='coerce')
- 如果是第0行的球队名称被误转换,可以先提取名称再处理其他行:
# 先保存球队名称 team_names = matches.iloc[0, [0, 2]] # 只转换第1行及之后的数值列 matches.iloc[1:, [0, 2]] = matches.iloc[1:, [0, 2]].apply(pd.to_numeric, errors='coerce') # 把球队名称放回第0行 matches.iloc[0, [0, 2]] = team_names
内容的提问来源于stack exchange,提问作者Marek Nowaczek
相关产品推荐
相关产品推荐

