如何优化Python Pandas大体积基因表达DataFrame转置及合并运算效率
性能优化核心建议
- 替换循环拼接逻辑,使用
pandas.melt做宽表转长表:原有代码中create_fixed_gene_df函数逐行遍历转置后的表、反复拼接DataFrame是最大的性能瓶颈,6万行800列的表用循环拼接会产生大量中间对象,内存开销和耗时都是指数级上升。melt是pandas内置的向量化宽转长函数,无需循环即可直接生成目标长表结构。 - 优化数据类型读取:原有代码读取所有列都用
dtype='str',表达量字段实际是数值类型,可在读表时指定dtype参数,仅将GENEID设为字符串,其余个体列设为数值类型,降低内存占用同时提升后续处理速度。 - 优化关联逻辑:提前将注释表的
ENSG设为索引,使用join替代merge,走索引关联的速度远高于普通merge;也可以提前将ENSG到EntrezGene ID、HGNC symbol的映射做成字典,用map方式赋值,关联速度会更快。 - 读写速度优化:如果使用pandas 2.0及以上版本,可在
read_csv和to_csv时指定engine='pyarrow',文本读写速度可提升数倍。
优化后代码示例
import pandas as pd import tqdm filenames = ["filename1", "filename2"] # 提前处理注释表,设置索引加速关联,只读需要的列减少内存占用 merge_file = pd.read_csv( "mergefile_123.tsv", sep="\t", dtype='str', usecols=["ENSG","EntrezGene ID","HGNC symbol"] ).set_index("ENSG") for f in tqdm.tqdm(filenames): # 读表时指定类型,仅GENEID为字符串 df = pd.read_csv( f, sep="\t", dtype={"GENEID": str} ) # 直接宽转长,一行替代原来的转置+循环拼接逻辑 fixed_gene_df = df.melt( id_vars=["GENEID"], var_name="person_id", value_name="expression" ) # 索引join替代merge,速度更快 merge_symbol_df = fixed_gene_df.join(merge_file, on="GENEID", how="left") # 重命名+筛选字段后输出 final_df = merge_symbol_df.rename( columns={"EntrezGene ID":"locus", "HGNC symbol":"geneSymbol"} )[["GENEID","geneSymbol","locus","person_id","expression"]] final_df.to_csv( f"{f.split('.tsv')[0]}_transposed_file.tsv", sep="\t", index=False # 开启pyarrow引擎可大幅提升输出速度,需提前安装pyarrow库 # engine='pyarrow' )
Pandas能力提升建议
- 优先通读pandas官方用户指南的「重塑和透视表」「性能优化」两个章节,熟练掌握内置的向量化操作接口,绝大多数表格变形需求都不需要自己写循环实现。
- 日常处理数据时多关注
pandas的原生函数,尽量避免使用iterrows、itertuples这类逐行遍历接口,更不要在循环中反复拼接DataFrame。
内容的提问来源于stack exchange,提问作者decabytes
相关产品推荐
相关产品推荐

