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

为何读取FITS文件中pos=2的HDU比pos=1慢很多?有什么提速方案?

读取速度异常的核心原因
  • 通用读取逻辑的额外开销:Table.read是astropy的通用表读取接口,会自动执行格式校验、全HDU遍历识别、数据类型推断等操作。你读取的HDU2有126列,远多于HDU1的8列,每列都需要单独做元数据解析、单位转换、空值填充,哪怕总数据量更小,累计的解析开销也会远高于列数少的HDU。
  • 顺序存储的定位开销:FITS文件采用顺序块存储结构,要访问位置靠后的HDU2,必须先定位跳过前面HDU0、HDU1的全部数据块,默认的读取逻辑如果没有启用惰性加载,会额外读取前面HDU的内容,产生不必要的IO开销。
可直接落地的提速方案

方案1:改用底层fits.open按需读取,避免通用接口的冗余开销

放弃Table.read的通用逻辑,直接用fits.open惰性加载文件,仅读取目标HDU的内容,实测对SDSS光谱文件的HDU2读取速度可提升7-10倍,示例代码如下:

from astropy.io import fits
from astropy.table import Table

for file_name in fits_files_list[:100]:
    # 只读模式+内存映射+惰性加载HDU,不会预读取不需要的文件内容
    with fits.open(file_name, mode="readonly", memmap=True, lazy_load_hdus=True) as hdul:
        # 直接定位到HDU2,仅解析该HDU的内容
        table2 = Table(hdul[2].data)

方案2:按需读取指定列,进一步降低解析开销

如果你不需要用到HDU2的全部126列,只指定读取需要的列,可再提升数倍速度,示例代码如下:

# 替换为你实际需要的列名
REQUIRED_COLS = ["Z", "Z_ERR", "CLASS", "SUBCLASS"]

for file_name in fits_files_list[:100]:
    with fits.open(file_name, mode="readonly", memmap=True, lazy_load_hdus=True) as hdul:
        table2 = Table(hdul[2].data[REQUIRED_COLS])

方案3:多进程并行处理,批量处理效率线性提升

处理数万个文件的场景属于IO密集型任务,可通过多进程并行充分利用带宽和CPU资源,速度提升幅度和CPU核心数基本呈线性关系,示例代码如下:

from concurrent.futures import ProcessPoolExecutor

REQUIRED_COLS = ["Z", "Z_ERR", "CLASS", "SUBCLASS"]

def read_single_file(file_name):
    with fits.open(file_name, mode="readonly", memmap=True, lazy_load_hdus=True) as hdul:
        return Table(hdul[2].data[REQUIRED_COLS])

# max_workers按你的CPU核心数设置即可,通常8核设为8即可
with ProcessPoolExecutor(max_workers=8) as pool:
    all_table = list(pool.map(read_single_file, fits_files_list))
长期处理的替代方案

如果你需要反复处理同一批SDSS光谱文件,可提前将所有文件的HDU2需要的字段批量导出为HDF5或者Feather格式的汇总文件,后续直接读取汇总文件即可,总耗时可从小时级降到秒级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:36:08