我看到越来越多的CSV文件包含多个部分,每个部分都包含自己的表.例如,此文件来自10XGenomics:

[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

有时,节标题甚至嵌入到它们自己的行中,例如

[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,

有没有一个可以直接处理这种切分的Python模块?我找不到如何使用Pandas 或csv模块来做到这一点.例如,从上面的两个例子中,我希望得到一个字典,每个部分有一个条目,然后是每个部分的列表列表.

有些部分有标题,如果这也能处理就好了,例如类似于csv.DictReader.

虽然编写一个可以解析这个特定示例的解决方案并不是特别困难,但要生成在一般情况下可以工作的解决方案要困难得多,例如,使用split就可以轻松地解析一个简单的CSV文件,而csv模块是400多行Python代码和更多的C代码行,所以我在这里真正寻找的是一个在一般情况下处理这个问题的模块.

PS:this question是相关的,但不幸的是,答案没有解决有关CSV解析器的问题

推荐答案

您可以使用configparser模块来读取您的文件:

from configparser import ConfigParser
import io
import pandas as pd

cfg = ConfigParser(allow_no_value=True)
cfg.optionxform = str
cfg.read('data.csv')

dfs = {}
for section in cfg.sections():
    buf = io.StringIO()
    buf.writelines('\n'.join(row.rstrip(',') for row in cfg[section]))
    buf.seek(0)
    dfs[section] = pd.read_csv(buf)

输出:

>>> dfs['gene-expression']
Empty DataFrame
Columns: [reference, /path/to/transcriptome]
Index: []

>>> dfs['libraries']
  fastq_id           fastqs         feature_types
0     gex1  /path/to/fastqs       Gene Expression
1     mux1  /path/to/fastqs  Multiplexing Capture

>>> dfs['samples']
  sample_id cmo_ids
0   sample1  CMO301
1   sample2  CMO303

现在,您还可以只想提取一个部分:

cfg = ConfigParser(allow_no_value=True)
cfg.optionxform = str
cfg.read('data.csv')

def read_data(section):
    buf = io.StringIO()
    buf.writelines('\n'.join(row.rstrip(',') for row in cfg[section]))
    buf.seek(0)
    return pd.read_csv(buf)

df = read_data('samples')

输出:

>>> df
  sample_id cmo_ids
0   sample1  CMO301
1   sample2  CMO303

Python相关问答推荐

在Python中管理多个OpenGVBO和VAO实例

Class_weight参数不影响RandomForestClassifier不平衡数据集中的结果

Pandas 填充条件是另一列

如何使用scipy从频谱图中回归多个高斯峰?

运行回文查找器代码时发生错误:[类型错误:builtin_index_or_system对象不可订阅]

Pandas 在最近的日期合并,考虑到破产

转换为浮点,pandas字符串列,混合千和十进制分隔符

无法连接到Keycloat服务器

如何启动下载并在不击中磁盘的情况下呈现响应?

Pandas GroupBy可以分成两个盒子吗?

Django—cte给出:QuerySet对象没有属性with_cte''''

如何从需要点击/切换的网页中提取表格?

通过追加列表以极向聚合

如何在Gekko中处理跨矢量优化

裁剪数字.nd数组引发-ValueError:无法将空图像写入JPEG

如何用FFT确定频变幅值

为罕见情况下的回退None值键入

如何获取包含`try`外部堆栈的`__traceback__`属性的异常

如何写一个polars birame到DuckDB

我怎么才能用拉夫分拣呢?