
本文详解如何使用pandas.wide_to_long()函数,仅针对带编号后缀的多组列(如name_1, Position_1, Country_2)进行定向长格式转换,保留其他结构列不变,完美解决PDF解析后球员信息横向铺开的典型数据规整难题。
本文详解如何使用pandas.wide_to_long()函数,**仅针对带编号后缀的多组列(如name_1, position_1, country_2)进行定向长格式转换**,保留其他结构列不变,完美解决pdf解析后球员信息横向铺开的典型数据规整难题。
在从可编辑PDF批量提取结构化数据时,一个常见痛点是:同一逻辑实体(如一支球队)的多个成员信息被“摊平”为重复模式的宽列——例如 name_1/Position_1/Country_1 和 name_2/Position_2/Country_2。这种宽格式虽便于人工阅读,却不利于后续分组聚合、可视化或建模。此时,盲目使用melt()会破坏语义分组(如将name_1和Position_2混为一列),而wide_to_long()正是为此类“规则性宽列”量身定制的精准工具。
wide_to_long() 的核心优势在于其模式识别能力:它能自动识别具有相同前缀+统一分隔符+数字后缀的列组(如name_1, name_2, Position_1, Position_2),并将其按编号索引(j参数)对齐重组,生成语义清晰的长表。相比melt()需手动枚举value_vars,它更简洁、更鲁棒、更不易出错。
以下为完整实现步骤与代码:
import pandas as pd
# 构造原始宽格式DataFrame(模拟PDF解析结果)
df = pd.DataFrame({
'Team': ["Bayern", "Barcelona", "Madrid"],
'region': ["Bravaria", "Barcelona", "Madrid"],
'title': ["Bundesliga", "Laliga", "Champions Leauge"],
'name_1': ["Robben", "Messi", "Ronaldo"],
'Position_1': ["RW", "ST", "ST"],
'Country_1': ["Netherlands", "Argentina", "Portugal"],
'name_2': ["Ribery", "Neymar", "Benzema"],
'Position_2': ["LW", "LW", "RW"],
'Country_2': ["FRANCE", "Brazil", "France"]
})
# ✅ 使用 wide_to_long 进行精准重塑
# - stubnames: 指定要“纵向展开”的列前缀列表(即语义组名)
# - i: 作为标识符的列名(保持为行索引或普通列)
# - j: 新生成的序号列名(对应原列后缀,如1,2)
# - sep: 列名中前缀与序号的分隔符(此处为下划线'_')
df_long = pd.wide_to_long(
df,
stubnames=['name', 'Position', 'Country'], # 必须是列名前缀,非完整列名
i='Team', # 作为分组键的列(也可传入list,如['Team','region'])
j='n', # 新增序号列名(默认为'variable',建议自定义)
sep='_'
).reset_index() # 将MultiIndex转为普通列(含Team和n)
print("重塑后的长格式DataFrame:")
print(df_long)输出结果:
Team n region title name Position Country 0 Bayern 1 Bravaria Bundesliga Robben RW Netherlands 1 Madrid 1 Madrid Champions Leauge Ronaldo ST Portugal 2 Barcelona 1 Barcelona Laliga Messi ST Argentina 3 Bayern 2 Bravaria Bundesliga Ribery LW FRANCE 4 Madrid 2 Madrid Champions Leauge Benzema RW France 5 Barcelona 2 Barcelona Laliga Neymar LW Brazil
⚠️ 关键注意事项:
- stubnames 必须严格匹配列名前缀(如'name'对应name_1, name_2),不能写成'name_1';
- 所有目标列必须遵循完全一致的命名模式(prefix + sep + number),否则会被忽略;
- i 参数支持单列或列名列表(如 i=['Team', 'region']),确保所有标识列在结果中完整保留;
- 若需进一步清理(如删除序号列n),可直接 df_long.drop('n', axis=1);
- 对于更复杂模式(如name_first, name_second),可先用df.rename(columns={...})标准化列名再调用。
相比melt()+str.split()+pivot()的多步组合,wide_to_long()以声明式语法一步到位,大幅提升代码可读性与维护性。它是处理“重复测量”“多期指标”“多成员属性”等场景的首选方案,也是Pandas数据规整工作流中不可或缺的利器。

















