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

是否存在可处理带分段结构CSV文件的Python模块?

解析含多分段的CSV文件(如10X Genomics格式)

问题场景

你会遇到这类CSV文件:包含多个独立表格分段,每个分段以[segment-name]标识,常见两种格式:

  1. 分段标题单独成行,后续是对应CSV表格:
    [gene-expression]
    reference,/path/to/transcriptome
    
    [libraries]
    fastq_id,fastqs,feature_types
    gex1,/path/to/fastqs,Gene Expression
    mux1,/path/to/fastqs,Multiplexing Capture
    
    [samples]
    sample_id,cmo_ids
    sample1,CMO301
    sample2,CMO303
    
  2. 分段标题嵌入CSV行(带空列,如[segment-name],,):
    [gene-expression],,
    reference,/path/to/transcriptome,
    [libraries],,
    fastq_id,fastqs,feature_types
    gex1,/path/to/fastqs,Gene Expression
    mux1,/path/to/fastqs,Multiplexing Capture
    [samples],,
    sample_id,cmo_ids,
    sample1,CMO301,
    sample2,CMO303,
    

目标是解析为字典:键为分段名,值是结构化数据(列表或类csv.DictReader对象)。

解决方案

1. 自定义通用解析函数(无额外依赖)

用Python内置csv模块写通用逻辑,兼容两种格式:

import csv
from typing import Dict, List

def parse_segmented_csv(file_path: str) -> Dict[str, List[Dict]]:
    parsed = {}
    current_segment = None
    headers = []

    with open(file_path, 'r', newline='') as f:
        for row in csv.reader(f):
            # 过滤全空行
            cleaned_cells = [cell.strip() for cell in row if cell.strip()]
            if not cleaned_cells:
                continue

            # 识别分段标题(两种格式适配)
            first_cell = cleaned_cells[0]
            if first_cell.startswith('[') and first_cell.endswith(']'):
                current_segment = first_cell.strip('[]')
                parsed[current_segment] = []
                headers = []
                continue

            # 处理当前分段的表头和数据行
            if current_segment is not None:
                if not headers:
                    headers = [h.strip() for h in row if h.strip()]
                else:
                    data_row = {}
                    for idx, header in enumerate(headers):
                        data_row[header] = row[idx].strip() if idx < len(row) else ''
                    parsed[current_segment].append(data_row)
    
    return parsed

使用示例:

data = parse_segmented_csv("your_10x_file.csv")
# 查看gene-expression分段
print(data["gene-expression"])
# 遍历libraries分段
for lib in data["libraries"]:
    print(f"{lib['fastq_id']}: {lib['feature_types']}")

2. 用configobj适配类INI格式(仅支持第一种格式)

如果你的文件是第一种纯分段标题行的格式,可以结合configobj和csv模块:

from configobj import ConfigObj
import csv
from io import StringIO

def parse_with_configobj(file_path: str) -> Dict[str, List[Dict]]:
    config = ConfigObj(file_path, encoding='utf-8')
    result = {}
    for section in config:
        # 把分段内容转为CSV字符串
        csv_content = "\n".join([f"{k},{v}" for k, v in config[section].items()])
        # 用DictReader解析
        result[section] = list(csv.DictReader(StringIO(csv_content)))
    return result

注意:这个方法只适配第一种格式,第二种格式需要先预处理去掉多余的空列。

总结

  • 自定义解析函数无需额外依赖,兼容两种常见格式,是最通用的选择
  • 若处理的文件都是类INI的纯分段格式,configobj可以简化部分逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:42:26