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

使用anndata.concat合并Tabula Sapiens的h5ad文件后体积暴涨4倍导致内存问题的咨询

anndata.concat合并Tabula Sapiens的h5ad文件后体积暴涨4倍导致内存问题的咨询

问题描述

我刚接触anndata,想请教下我遇到的这个问题是正常现象吗?

我有28个Tabula Sapiens的h5ad文件,单个文件总大小是53GB,我想把它们合并成一个h5ad文件来计算统计量,用的代码如下:

# Initialize an empty AnnData object
merged_adata = None
input_files = os.listdir("/full_data/ts_individual_data/}"
# Read and concatenate each file
for file in input_files:
    print(f"Processing file: {file}")
    adata = sc.read_h5ad(f"/full_data/ts_individual_data/{file}")
    print(f"Read Done for {file}")
    
    
    if merged_adata is None:
        merged_adata = adata
    else:
        merged_adata = ad.concat([merged_adata, adata], axis=0, join='outer', merge='unique')

# Write the merged data to the output file in chunks
print(f"Writing merged data to {output_file}")
merged_adata.write_h5ad(output_file)

合并完成后,我发现总文件大小居然达到了222GB——是原文件总大小的4倍多。我已经检查过var和obs层没有重复条目,还比对了几个cell_id在合并文件和原单个组织文件里的表达值,结果都是一致的,但现在这个超大的文件导致我遇到了严重的内存问题,想请教:

  1. 我合并这些h5ad文件的方法是正确的吗?
  2. 有什么办法可以解决这种体积暴涨的问题?

问题解答

首先,你的合并核心思路是没问题的,但文件体积暴涨主要和合并参数、数据存储格式有关,我们一步步来拆解解决:

1. 先确认合并参数是否必要

你用了join='outer'+merge='unique',这会保留所有输入文件的所有基因(var)和注释信息。如果Tabula Sapiens的不同组织其实用的是同一套基因注释(这在标准化单细胞数据集里很常见),完全可以把join='inner',只保留所有组织共有的基因,这能直接砍掉大量冗余的基因维度,大幅降低文件体积。

如果确实需要保留所有基因,那outer join是必须的,但我们可以从存储格式入手优化。

2. 确保表达矩阵是稀疏存储

单细胞数据的表达矩阵里90%以上的值都是0,原单个文件大概率是用稀疏矩阵存储的(比如scipy.sparse.csr_matrix),但合并过程中如果触发了稀疏转密集的操作(比如某些join场景下的自动补全),就会导致体积暴涨——因为密集矩阵会把所有0都实实在在地存下来,而稀疏矩阵只存非零元素。

你可以先检查合并后的矩阵类型:

print(type(merged_adata.X))
print(f"非零元素数量: {merged_adata.X.nnz}")

如果输出不是稀疏矩阵(比如是numpy.ndarray),赶紧转成稀疏格式:

from scipy.sparse import csr_matrix
merged_adata.X = csr_matrix(merged_adata.X)

这一步能把体积砍回接近原文件总和的水平。

3. 写入时开启压缩

anndata的write_h5ad默认是不压缩的,开启压缩能进一步大幅减小文件体积,而且读取时会自动解压,完全不影响后续分析。推荐用lzf压缩(速度快,压缩率也不错),或者gzip(压缩率更高,速度稍慢):

merged_adata.write_h5ad(output_file, compression='lzf')

这一步一般能把体积再压缩30%-50%。

4. 砍掉冗余的注释信息

你已经检查过obs/var没有重复,但可以再看看有没有不需要的layers、obsm、varm等附加信息——如果某些层对你后续的统计分析没用,合并前就可以删掉,比如:

# 读取单个文件后,只保留需要的内容
adata = adata[:, :].copy()  # 保留主表达矩阵
adata.layers.pop('raw_counts')  # 删掉不需要的冗余layer

冗余的附加信息也是体积暴涨的潜在原因。

5. 修正代码里的语法错误

最后提个小细节:你代码里的input_files = os.listdir("/full_data/ts_individual_data/}"有语法错误——多了个},引号也不匹配,运行时会报错,记得修正成:

input_files = os.listdir("/full_data/ts_individual_data/")

备注:内容来源于stack exchange,提问作者Danish Zahid Malik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:17:59