You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas拆分扁平化JSON生成的多列员工信息DataFrame?

解决嵌套JSON扁平化DataFrame的拆分问题

针对你提到的列名格式(如employee_0_salary、employee_0_skills_0_id),可以通过正则解析列结构+长格式转换的方式实现需求,以下是具体步骤和代码:

方法一:正则解析+分步转换(适配复杂结构)

这种方法适合列名格式不完全统一的场景,容错性更强:

1. 解析员工相关列的结构

先提取所有employee_开头的列,通过正则拆分出员工索引、属性名称、技能索引等信息:

import pandas as pd
import re

# 正则匹配规则:匹配employee_<员工号>_<属性>_<技能号>_<技能属性>的结构
pattern = re.compile(r'employee_(\d+)_([a-z]+)(?:_(\d+)_([a-z]+))?')

# 筛选员工相关列并解析
employee_cols = [col for col in df.columns if col.startswith('employee_')]
col_details = []
for col in employee_cols:
    match_result = pattern.match(col)
    if match_result:
        emp_idx, attr, skill_idx, skill_attr = match_result.groups()
        col_details.append({
            'col_name': col,
            'emp_idx': int(emp_idx),
            'attr': attr,
            'skill_idx': int(skill_idx) if skill_idx else None,
            'skill_attr': skill_attr
        })
col_df = pd.DataFrame(col_details)

2. 转换薪资数据为长格式

单独提取薪资列,转换为id + emp_idx + salary的结构:

# 筛选薪资列
salary_col_list = col_df[col_df['attr'] == 'salary']['col_name'].tolist()
salary_temp = df[['id'] + salary_col_list]

# 转长格式并提取员工索引
salary_long = salary_temp.melt(id_vars='id', var_name='temp_col', value_name='salary')
salary_long['emp_idx'] = salary_long['temp_col'].str.extract(r'employee_(\d+)_salary').astype(int)
salary_long = salary_long.drop('temp_col', axis=1)

3. 转换技能ID数据为长格式

同样处理技能ID列,得到id + emp_idx + skill_idx + skills_id的结构:

# 筛选技能ID列
skill_col_list = col_df[(col_df['attr'] == 'skills') & (col_df['skill_attr'] == 'id')]['col_name'].tolist()
skill_temp = df[['id'] + skill_col_list]

# 转长格式并提取索引
skill_long = skill_temp.melt(id_vars='id', var_name='temp_col', value_name='skills_id')
skill_long[['emp_idx', 'skill_idx']] = skill_long['temp_col'].str.extract(r'employee_(\d+)_skills_(\d+)_id').astype(int)
skill_long = skill_long.drop('temp_col', axis=1)

4. 合并数据得到目标结构

将薪资和技能数据按id和emp_idx合并,保留需要的列:

# 合并数据(how='left'确保所有技能行都被保留,可根据需求调整)
final_df = pd.merge(skill_long, salary_long, on=['id', 'emp_idx'], how='left')
# 整理列顺序并去除空值(可选)
final_df = final_df[['id', 'salary', 'skills_id']].dropna(subset=['salary', 'skills_id'])

方法二:用wide_to_long快速转换(适配规整结构)

如果所有员工相关列的格式完全统一(比如每个员工都有salary和多层skills),可以用Pandas的wide_to_long工具分两步完成,代码更简洁:

# 第一步:将员工层级转为长格式
emp_long = pd.wide_to_long(df, stubnames=['employee'], i='id', j='emp_idx', sep='_', suffix='\\d+')
emp_long = emp_long.reset_index()

# 第二步:将技能层级转为长格式
skill_long = pd.wide_to_long(emp_long, stubnames=['skills'], i=['id', 'emp_idx'], j='skill_idx', sep='_', suffix='\\d+')

# 提取目标列并重命名
final_df = skill_long.reset_index()[['id', 'employee_salary', 'skills_id']].rename(columns={'employee_salary': 'salary'})

注意:这种方法要求列名严格遵循employee_<n>_<attr>、employee_<n>_skills_<m>_<attr>的格式,否则会出现匹配错误。

内容的提问来源于stack exchange,提问作者Nathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:06:27