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

如何用Python/Pandas自动识别多表头CSV的表头位置并提取信息

多块表头CSV的自动识别与提取方案

针对包含多个独立数据块的CSV文件,我们可以通过逐行分析的方式自动识别每个块的表头位置,并提取结构化的表头信息。

核心思路

你的CSV文件每个数据块遵循固定结构:

  1. 块标题行:仅第一个单元格有内容(如"Level and Distortion"),其余为空
  2. 通道/指标行:定义各数据列对应的通道或指标(如"Ch1 (F)")
  3. XY标识行:标记每列是X轴还是Y轴数据(如"X,Y,X,Y...")
  4. 单位行:定义各列数据的单位(如"Hz,Vrms...")
  5. 数据行:以数字开头,直到下一个块标题行出现

我们通过识别块标题行作为新块的起点,通过数据行的特征判断表头的终点,从而定位每个块的表头范围。

代码实现

import csv

def identify_csv_headers(csv_path):
    headers_info = []
    current_block = None

    with open(csv_path, 'r', newline='', encoding='utf-8') as f:
        reader = csv.reader(f)
        for line_num, row in enumerate(reader, start=1):
            # 清理行内容,去除引号和空单元格
            cleaned_cells = [cell.strip('"') for cell in row]
            non_empty_cells = [cell for cell in cleaned_cells if cell]

            # 识别块标题行:仅一个非空单元格,且不是数据/表头关键字开头
            if len(non_empty_cells) == 1:
                title = non_empty_cells[0]
                if not title.startswith(('X', 'Hz', 'Ch', 's')):
                    # 保存上一个块(如果存在)
                    if current_block:
                        headers_info.append(current_block)
                    # 初始化新块
                    current_block = {
                        'block_title': title,
                        'start_line': line_num,
                        'header_rows': [cleaned_cells]
                    }
                    continue

            # 处理当前块的表头行
            if current_block is not None:
                # 判断是否是数据行:首单元格为数字(支持科学计数法)
                first_cell = cleaned_cells[0]
                if first_cell.replace('.', '').replace('E-', '').replace('E+', '').isdigit():
                    # 数据行开始,表头结束
                    current_block['end_line'] = line_num - 1
                    # 解析表头各层信息
                    current_block['channels'] = [cell for cell in current_block['header_rows'][1] if cell]
                    current_block['xy_labels'] = [cell for cell in current_block['header_rows'][2] if cell]
                    current_block['units'] = [cell for cell in current_block['header_rows'][3] if cell]
                    headers_info.append(current_block)
                    current_block = None
                else:
                    # 加入表头行
                    current_block['header_rows'].append(cleaned_cells)

        # 处理最后一个未闭合的块
        if current_block:
            current_block['end_line'] = line_num
            current_block['channels'] = [cell for cell in current_block['header_rows'][1] if cell]
            current_block['xy_labels'] = [cell for cell in current_block['header_rows'][2] if cell]
            current_block['units'] = [cell for cell in current_block['header_rows'][3] if cell]
            headers_info.append(current_block)

    return headers_info

# 使用示例
if __name__ == "__main__":
    csv_path = "your_data.csv"
    result = identify_csv_headers(csv_path)

    # 打印提取的表头信息
    for i, block in enumerate(result, 1):
        print(f"--- 数据块 {i} ---")
        print(f"标题: {block['block_title']}")
        print(f"表头行范围: 第 {block['start_line']} 行 至 第 {block['end_line']} 行")
        print(f"通道/指标: {block['channels']}")
        print(f"XY标识: {block['xy_labels']}")
        print(f"单位: {block['units']}\n")

代码说明

  • 块标题识别:通过判断行内仅一个非空单元格,且内容不是数据行的关键字(如Hz、X、Ch)来定位新的数据块
  • 表头范围确定:当遇到首单元格为数字(支持科学计数法)的行时,判定为数据行,此时前一行即为表头的最后一行
  • 结构化提取:将每个块的表头拆分为通道/指标、XY标识、单位三个维度,方便后续处理
  • 兼容性处理:考虑了CSV中的引号、空单元格,以及最后一个数据块的收尾逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:34:52