IDL提供了专门针对HDF5科学数据格式的读写函数库。可以参考IDL帮助的Routines (alphabetical) > Routines: H > HDF5 Routines 这个章节查看函数列表。

如果只是简单的读写HDF5文件,可以利用下面三个函数即可:

  • H5_GETDATA        读取数据
  • H5_LIST                查看数据列表
  • H5_PUTDATA        写入数据

注:上面3个函数用法非常简单,这里不再举例。要求IDL最低版本为8.3。

下面介绍如何将一个大数据分块写入HDF5文件。在test_write_h5d.pro源码中,分成了如下几个步骤

(1)首先随机创建一个大数据,利用了hanning函数(生成汉宁窗,主要用于快速傅里叶变换),再计算两个维度的步长、步数。

(2)然后将第一个分块数据写入数据集,并进行第一个分块数据的可视化展示。

(3)最后是一个嵌套循环,将剩余分块数据动态写入,并叠加展示每一个分块数据。

下图为可视化结果,左侧图形为分块效果,右侧图形为整体数据效果。 

大数据写入sqlserver python 大数据写入hdf5_h5

图:可视化效果

最后附上源码:

PRO test_write_h5d
  COMPILE_OPT idl2

  ; 创建新的 HDF5文件,可修改
  file = 'D:\temp\mytest_h5_file.h5'
  fid = H5F_CREATE(file)

  ; 随机创建初始维度
  random_number1 = SORT(RANDOMU(seed, 1000))
  random_number2 = SORT(RANDOMU(seed, 2000))
  dim1 = random_number1[0]>500
  dim2 = random_number2[0]>1000

  ; 每一个维度的分块步长
  step1 = 100
  step2 = 200

  ; 每一个维度的分块数目
  nstep1 = dim1/step1
  nstep2 = dim2/step2

  ; 重新定义大数据维度,可以完美分块
  dim1 = nstep1*step1
  dim2 = nstep2*step2

  ; 创建一个大数据
  data = hanning(dim1,dim2)

  ; 取出第一个分块数据
  data_segment = data[0:(step1-1),0:(step2-1)]

  ; 展示第一个分块数据
  s = surface(data_segment, title='分块效果展示', $
    xrange=[0,dim1-1], yrange=[0,dim2-1], layout=[2,1,1],$
    dimensions=[900,500], margin=[.2,.2,.2,.2])

  ; 根据数据创建一个datatype
  datatype_id = H5T_IDL_CREATE(data)

  ; 创建一个dataspace,并且可以进行扩展
  dataspace_id = H5S_CREATE_SIMPLE([step1,step2],$
    max_dimensions=[-1,-1])

  ; 创建一个dataset
  dataset_id = H5D_CREATE(fid,'Hanning', datatype_id,$
    dataspace_id, chunk_dimensions=[step1,step2])

  ; 扩展dataset的维度,以适应第一个分块数据
  H5D_EXTEND,dataset_id,SIZE(data_segment,/dimensions)

  ; 将第一个分块数据写入dataset
  H5D_WRITE,dataset_id,data_segment

  ; 同上面操作相似,将剩下的数据分块写入到HDF5文件中
  FOR ind1 = 0L, nstep1-1 DO BEGIN
    FOR ind2 = 0L, nstep2-1 DO BEGIN

      ; 如果文件dataspace已存在,则关闭
      IF (ISA(iter_data_space_id)) THEN BEGIN
        H5S_CLOSE, iter_data_space_id
      ENDIF

      ; 如果memory dataspace已存在,则关闭
      IF (ISA(iter_data_space_id2)) THEN BEGIN
        H5S_CLOSE, iter_data_space_id2
      ENDIF

      ; 计算当前分块的起始行列号
      start1 = ind1 * step1
      start2 = ind2 * step2

      ; 获取当前分块数据
      data_segment = data[start1:(start1+step1-1),start2:(start2+step2-1)]
      
      ; 展示当前分块数据
      s = surface(data_segment, layout=[2,1,1], $
        LINDGEN(step1)+start1, LINDGEN(step2)+start2, /overplot)

      ; 扩展dataset维度,输入维度应该是扩展后维度,而不是新增的维度
      H5D_EXTEND, dataset_id, [start1+step1, start2+step2]

      ; 创建新的dataspace
      iter_data_space_id = H5D_GET_SPACE(dataset_id)

      ; 选中包含当前分块数据的 slab
      H5S_SELECT_HYPERSLAB, iter_data_space_id, [start1,start2], $
        [step1,step2], /RESET

      ; 创建memory data space
      iter_data_space_id2 = H5S_CREATE_SIMPLE([step1,step2])

      ; 使用文件dataspace和 Memory dataspace,将当前分块数据写入Dataset
      H5D_WRITE, dataset_id, data_segment, $
        FILE_SPACE_ID=iter_data_space_id,$
        MEMORY_SPACE_ID=iter_data_space_id2
    ENDFOR
  ENDFOR

  ; 关闭前边打开的标识符
  H5S_CLOSE, iter_data_space_id
  H5S_CLOSE, iter_data_space_id2
  H5S_CLOSE,dataspace_id
  H5D_CLOSE,dataset_id
  H5T_CLOSE,datatype_id
  H5F_CLOSE,fid

  HELP, data

  ; 读取新建的HDF5数据列表
  h5_list, file
  ; 获取数据并进行可视化
  in_dat = H5_GETDATA(file, '/Hanning')
  s=surface(in_dat, layout=[2,1,2], /current, $
    margin=[.2,.2,.2,.2], title='完整数据展示')

END