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

读取含多级分组类透视CSV并转换为Pandas DataFrame的方法

这个问题我刚好处理过类似的,给你一套完整的解决方案,一步步来:

核心思路

你的数据是典型的层级缩进式透视数据,核心逻辑是:通过前导空格数确定每行的层级,追踪父层级的名称并向下填充到子节点,最后只保留最底层(Level4)的行,计算a-b的差值并整理成目标格式。


步骤1:读取并筛选有效数据

因为开头存在无关文本行,我们先读取所有行,动态定位到表头行(包含header A和header B的行),从下一行开始提取有效数据,这样不管开头有多少无关行都能准确识别。

步骤2:识别层级并追踪父节点

每行的前导空格数除以3就是对应的层级(0→Level0,3→Level1,…,12→Level4)。我们需要维护一个字典来记录当前各层级的名称:

  • 遇到Level0行时,更新Level0的值,并重置Level1到Level4为空
  • 遇到Level1行时,更新Level1的值,重置Level2到Level4为空,以此类推
  • 只有当Level4有值时,说明这是一个叶子节点,我们才收集这条数据(因为你的示例结果只包含Level4的行)

步骤3:计算差值并调整列顺序

对每个叶子节点计算Diff(a,b) = a - b,最后把列调整成你需要的顺序:Level4, Diff(a,b), Level0, Level1, Level2, Level3


完整代码示例
import pandas as pd

# 1. 读取文件并筛选有效数据
with open('your_data.csv', 'r') as f:
    lines = f.readlines()

# 定位表头行(包含header A和header B的行)
header_index = None
for idx, line in enumerate(lines):
    if 'header A' in line and 'header B' in line:
        header_index = idx
        break

# 提取表头之后的有效数据行
data_lines = lines[header_index + 1:]

# 2. 处理每行,识别层级并追踪父节点
current_levels = {
    'Level0': None,
    'Level1': None,
    'Level2': None,
    'Level3': None,
    'Level4': None
}
processed_rows = []

for line in data_lines:
    line = line.strip('\n')
    if not line:
        continue  # 跳过空行
    
    # 计算前导空格数,确定层级
    leading_spaces = len(line) - len(line.lstrip())
    level = leading_spaces // 3
    
    # 分割行数据:名称、a值、b值(处理逗号后的空格)
    parts = [p.strip() for p in line.split(',')]
    node_name = parts[0]
    a_value = float(parts[1])
    b_value = float(parts[2])
    
    # 更新当前层级的名称,重置子层级
    if level == 0:
        current_levels['Level0'] = node_name
        current_levels['Level1'] = None
        current_levels['Level2'] = None
        current_levels['Level3'] = None
        current_levels['Level4'] = None
    elif level == 1:
        current_levels['Level1'] = node_name
        current_levels['Level2'] = None
        current_levels['Level3'] = None
        current_levels['Level4'] = None
    elif level == 2:
        current_levels['Level2'] = node_name
        current_levels['Level3'] = None
        current_levels['Level4'] = None
    elif level == 3:
        current_levels['Level3'] = node_name
        current_levels['Level4'] = None
    elif level == 4:
        current_levels['Level4'] = node_name
    else:
        continue  # 超出Level4的行忽略
    
    # 只收集Level4存在的叶子节点数据
    if current_levels['Level4'] is not None:
        processed_rows.append({
            'Level0': current_levels['Level0'],
            'Level1': current_levels['Level1'],
            'Level2': current_levels['Level2'],
            'Level3': current_levels['Level3'],
            'Level4': current_levels['Level4'],
            'Diff(a,b)': a_value - b_value
        })

# 3. 生成目标DataFrame并调整列顺序
result_df = pd.DataFrame(processed_rows)
result_df = result_df[['Level4', 'Diff(a,b)', 'Level0', 'Level1', 'Level2', 'Level3']]

# 查看结果
print(result_df)

示例效果

假设你的CSV内容是:

无关文本行1
无关文本行2
header A, header B
C, 1000, 475
   c1, 800, 300
      c2, 500, 200
         c3, 600, 75
            x7, 600, 75
D, 2000, 1000
   d1, 1500, 800
      d2, 900, 300
         d3, 700, 100
            x8, 700, 100

运行代码后会输出:

Level4  Diff(a,b) Level0 Level1 Level2 Level3
0     x7      525.0      C     c1     c2     c3
1     x8      600.0      D     d1     d2     d3

完全符合你给出的示例要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:31