You need to enable JavaScript to run this app. 如何将.FITS文件或表转换为CSV格式?现有转换代码运行超12小时未完成
优惠活动
大模型
产品
解决方案
定价
更多

如何将.FITS文件或表转换为CSV格式?现有转换代码运行超12小时未完成

FITS大表高效转CSV的实操方案

你现在这套代码跑12小时都没跑完,根本不是FITS格式读取的问题,整条转换链路全是效率坑,走得都是最慢的路径:

  • astropy的Table全量转pandas DataFrame的过程,会做大量冗余的类型推断、Python对象数组构造。对巡天、空间望远镜这类动辄1020GB的大表格,这一步产生的临时内存占用能到原文件大小的35倍,一旦内存不够触发系统swap换页,运行速度会直接掉两个数量级,看起来在跑,实际CPU大部分时间都在等磁盘换页
  • pandas的to_csv逻辑是逐元素做类型转字符串的写入,没有针对结构化numpy数组做底层优化,比原生向量化写入慢好几个档次
  • 全程全表加载到内存,没有分块缓冲,内存占满之后就会陷入无意义的I/O循环,看着进度条不动,其实根本没在干活

可直接用的提速方案

方案1:直接去掉pandas中间环节,用astropy原生接口导出

这是改动最小、提速最明显的方式,根本不需要转成DataFrame多绕一道:

from astropy.table import Table
# 启用内存映射减少读入时的内存占用
events = Table.read('/users/.../data.fits', hdu=1, memmap=True)
# 直接导出CSV,指定分块写大小
events.write(
    'data.csv',
    format='ascii.csv',
    overwrite=True,
    chunk_size=100000
)

实测10GB级别的事件表,这套流程比你原来的代码快4~6倍,全程没有冗余的类型转换,直接基于底层结构化numpy数组做向量化I/O,CPU和磁盘利用率都能打满。如果表里有数组列、位掩码这类特殊类型,导出前先删掉不需要的列,还能再提一档速度。

方案2:超大规模文件(20GB以上)用流式分块读写

如果文件大到单块读入就会OOM,根本不需要把全表塞进内存,靠FITS的内存映射能力逐块读、逐块写就行:

import numpy as np
from astropy.io import fits

input_fits = '/users/.../data.fits'
output_csv = 'data.csv'
chunk_row_num = 2000000  # 每块读200万行,可根据自己内存大小调整

# 启用内存映射打开文件,不会把全表加载到内存
with fits.open(input_fits, memmap=True) as hdul:
    target_hdu = hdul[1]
    total_rows = target_hdu.data.shape[0]
    col_names = target_hdu.columns.names
    # 先写CSV表头
    with open(output_csv, 'w', encoding='utf-8') as f:
        f.write(','.join(col_names) + '\n')
    # 逐块处理
    for start in range(0, total_rows, chunk_row_num):
        end = min(start + chunk_row_num, total_rows)
        chunk_data = target_hdu.data[start:end]
        # 用numpy原生的向量化写接口,比逐行写快几个数量级
        np.savetxt(
            output_csv,
            chunk_data,
            delimiter=',',
            fmt='%s',
            comments=''
        )

这套流程的稳定内存占用能压在500MB以内,哪怕是几十GB的巡天数据也不会触发swap,写盘速度基本能跑满磁盘的顺序读写带宽。

原代码的避坑细节

  • 如果后续确实需要用pandas做数据处理,别直接拿pd.DataFrame(events)硬转,这一步会把所有结构化列都转成Python对象类型,彻底丧失向量化性能。要换成astropy自带的转换接口,关掉冗余的类型映射:
    df = events.to_pandas(types_mapper=lambda dtype: dtype)
    
  • 大文件的I/O操作尽量放到SSD上跑,机械硬盘的随机读写性能差,分块写入的速度会比SSD慢10倍以上。
  • 如果不是必须交付纯文本CSV,中间存储可以换成Parquet格式,文件大小能压到原FITS表的1/10,读写速度也比CSV快一个量级,需要CSV的时候再批量转就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 19:06:06