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

如何创建不覆盖的空NumPy数组,替代列表实现循环追加

解决方案:直接用NumPy数组存储大规模Phred质量数据

核心思路

NumPy数组是固定大小的,直接动态追加不仅效率极低,还容易出现数据覆盖问题。针对150×180000的大规模数据,最优方案是先预分配对应尺寸的数组,再通过循环填充数据,完全跳过列表存储环节。

实现步骤

  1. 先遍历一次FastQ文件,统计总读取数(reads)和每条序列的碱基长度(FastQ数据通常所有序列长度一致)
  2. 根据统计结果预分配NumPy数组(用uint8类型,Phred质量分范围0-60,足够存储且大幅节省内存)
  3. 再次遍历FastQ文件,将每条序列的Phred质量数据写入数组对应位置

修改后的代码

from Bio import SeqIO
import matplotlib.pyplot as plt
import gzip
import numpy as np

# 第一步:统计数据维度
with gzip.open("data.fastq.gz", 'rt') as input_file:
    sio = SeqIO.parse(input_file, "fastq")
    total_reads = 0
    read_length = None
    for r in sio:
        total_reads += 1
        if read_length is None:
            read_length = len(r.letter_annotations['phred_quality'])

# 预分配数组:维度为(total_reads, read_length),类型uint8
npa = np.zeros((total_reads, read_length), dtype=np.uint8)

# 第二步:填充数组
with gzip.open("data.fastq.gz", 'rt') as input_file:
    sio = SeqIO.parse(input_file, "fastq")
    for idx, r in enumerate(sio):
        npa[idx] = r.letter_annotations['phred_quality']

# 绘制箱线图
plt.boxplot(npa, showfliers=False)
plt.title("Quality Score Boxplot")
plt.xlabel("碱基位置")
plt.ylabel("读取数")
plt.show()

额外优化点

  • 若确定所有序列长度一致,可只取第一条序列的长度作为标准,减少一次遍历的计算量
  • uint8类型相比默认的int64能节省8倍内存,150×180000的数据内存占用从216MB降到27MB,大幅降低内存压力

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:51:03