我目前正在努力解决一个问题。我有 1500 个包含 3800 x 3800 数组的适合文件。我的目标是用它们创建一个单一的 HDF5 数据立方体。不幸的是,我无法提供 fit 文件(由于存储问题)。到目前为止,我已经能够通过执行以下操作创建具有所需形状(3800、3800、1500)的空 HDF5 数组:
import h5py
from astropy.io import fits
import glob
outname = "test.hdf5"
NAXIS1 = 3800
NAXIS2 = 3800
NAXIS3 = 1500
f = h5py.File(outname,'w')
dataset = f.create_dataset("DataCube",
(NAXIS1,NAXIS2,NAXIS3),
dtype=np.float32)
f.close()
但是我在尝试从 fit 文件中写入数组时遇到了麻烦,因为以下 for 循环中的每个元素至少需要 30 分钟:
f = h5py.File(outname,'r+')
# This is the actual line, but I will replace it by random noise
# in order to make the example reproducible.
# fitslist = glob.glob("*fits") # They are 1500 fits files
for i in range(NAXIS3):
# Again, I replace the real data with noise.
# hdul = fits.open(fitslist[i])
# file['DataCube'][:,:,i] = hdul[0].data
data = np.random.normal(0,1,(dim0,dim1))
file['DataCube'][:,:,i] = data
f.close()
有没有更好的方法来构建一个由 N 个切片组成的 3D 数据立方体,这些切片已经存储在 N 个 fit 文件中?我期待在光盘中创建 HDF5 文件后,写入它会非常快,但事实并非如此。
非常感谢您的帮助。
编辑 1:我测试了 astrofrog 提出的修改,效果非常好。现在的表现相当不错。除此之外,我将几个 fit 文件 (~50) 存储到一个临时 numpy 数组中,以减少我写入 hdf5 文件的次数。现在代码如下所示:
NAXIS1 = len(fitslist)
NAXIS2 = fits_0[ext].header['NAXIS1']
NAXIS3 = fits_0[ext].header['NAXIS2']
shape_array = (NAXIS2, NAXIS3)
print(shape_array)
f = h5py_cache.File(outname, 'w', chunk_cache_mem_size=3000*1024**2,
libver='latest')
dataset = f.create_dataset("/x", (NAXIS1, NAXIS2, NAXIS3),
dtype=np.float32)
cache_size = 50
cache_array = np.empty(shape=(cache_size, NAXIS2, NAXIS3))
j = 0
for i in tqdm(range(len(fitslist))):
print(fitslist[i])
hdul = fits.getdata(fitslist[i], ext)
cache_array[j:j+1, :, :] = hdul
if ((i % cache_size == 0) & (i != 0)):
print("Writing to disc")
f['/x'][i-cache_size+1:i+1, :, :] = cache_array
j = 0
if (i % 100 == 0):
print("collecting garbage")
gc.collect()
j = j + 1
f.close()
我的问题是:还有更多的pythonic方式吗?我不确定这是用 h5py 写入文件的最有效方法,还是有更好的方法从 fit 读取到 numpy 再到 hdf5。