HDF5

HDF5 (Hierarchical Data Format) 是一种常见的跨平台数据储存文件,可以表示非常复杂、异构的数据对象。DolphinDB 提供了 HDF5 插件,可以查看 HDF5 文件元数据,读写 HDF5 文件并自动转换数据类型。

在插件市场安装插件

版本要求

  • DolphinDB Server: 2.00.10 及更高版本
  • OS: x86-64 Linux, Windows

安装步骤

  1. 在 DolphinDB 客户端中使用 listRemotePlugins 命令查看插件仓库中的插件信息。

    login("admin", "123456");
    listRemotePlugins()
  2. 使用 installPlugin 命令完成插件安装。

    installPlugin("hdf5");
  3. 使用 loadPlugin 命令加载插件。

    loadPlugin("hdf5");

用户接口

ls

语法

ls(fileName)

参数

fileName STRING 类型标量,HDF5 文件名。

详情

列出一个 HDF5 文件中的所有对象(数据集(dataset)和组(group))以及对象类型(objType)。在对象类型中,数据集会包括其列数及行数。例如 DataSet{(7,3)}代表 7 列 3 行。

例子

ls("/smpl_numeric.h5")
/* 
output:
        objName	     objType
        --------------------
        /            Group
        /double	     DataSet{(7,3)}
        /float	     DataSet{(7,3)}
        /schar	     DataSet{(7,3)}
        /sint	     DataSet{(7,3)}
        /slong	     DataSet{(7,3)}
        /sshort	     DataSet{(7,3)}
        /uchar	     DataSet{(7,3)}
        /uint	     DataSet{(7,3)}
        /ulong	     DataSet{(1,1)}
        /ushort	     DataSet{(7,3)}
*/

ls("/named_type.h5")
/* 
output:
        objName      objType
        ----------------------
        /            Group
        /type_name   NamedDataType
*/

lsTable

语法

lsTable(fileName)

参数

fileName STRING 类型标量,HDF5 文件名。

详情

列出一个 HDF5 文件中的所有 table 信息,即 HDF5 数据集(dataset)对象信息,包括表名、列数及行数、表的类型。

例子

lsTable("/smpl_numeric.h5")

/*
output:
       tableName    tableDims	 tableType
       /double        7,3       H5T_NATIVE_DOUBLE
       /float	      7,3       H5T_NATIVE_FLOAT
       /schar	      7,3       H5T_NATIVE_SCHAR
       /sint	      7,3       H5T_NATIVE_INT
       /slong	      7,3       H5T_NATIVE_LLONG
       /sshort	      7,3       H5T_NATIVE_SHORT
       /uchar	      7,3       H5T_NATIVE_UCHAR
       /uint	      7,3       H5T_NATIVE_UINT
       /ulong	      1,1       H5T_NATIVE_ULLONG
       /ushort	      7,3       H5T_NATIVE_USHORT

*/

extractHDF5Schema

语法

extractHDF5Schema(fileName, datasetName)

参数

fileName STRING 类型标量,HDF5 文件名。

datasetName STRING 类型标量,dataset 名称,即表名。可通过 ls 或 lsTable 获得。

详情

生成 HDF5 文件中指定数据集的结构,包括两列:列名和数据类型。

例子

extractHDF5Schema("/smpl_numeric.h5","sint")
/*
output:
        name	type
        col_0	INT
        col_1	INT
        col_2	INT
        col_3	INT
        col_4	INT
        col_5	INT
        col_6	INT
*/

extractHDF5Schema("/compound.h5","com")
/*
output:
        name	type
        fs	STRING
        vs	STRING
        d	DOUBLE
        t	TIMESTAMP
        l	LONG
        f	FLOAT
        i	INT
        s	SHORT
        c	CHAR
*/

loadHDF5

语法

loadHDF5(fileName,datasetName,[schema],[startRow],[rowNum])

参数

fileName STRING 类型标量,HDF5 文件名。

datasetName STRING 类型标量,dataset 名称,即表名。可通过 ls 或 lsTable 获得。

schema 包含列名和列的数据类型的表。若要改变由系统自动决定的列的数据类型,需要在 schema 表中修改数据类型,并且把它作为loadHDF5函数的一个参数。

startRow INT 类型标量,从哪一行开始读取 HDF5 数据集。若不指定,默认从数据集起始位置读取。

rowNum INT 类型标量,读取 HDF5 数据集的行数。若不指定,默认读到数据集的结尾。

详情

将 HDF5 文件中的指定数据集加载为 DolphinDB 数据库的内存表。读取的行数为 HDF5 文件中定义的行数,而不是读取结果中的 DolphinDB 表的行数。支持的数据类型,以及数据转化规则可见数据类型章节。

例子

loadHDF5("/smpl_numeric.h5","sint")
/*
output:
        col_0	col_1	col_2	col_3	col_4	col_5	col_6
        (758)	8	(325,847)	87	687	45	90
        61	0	28	77	546	789	45
        799	5,444	325,847	678	90	54	0


scm = table(`a`b`c`d`e`f`g as name, `CHAR`BOOL`SHORT`INT`LONG`DOUBLE`FLOAT as type)
loadHDF5("../hdf5/h5file/smpl_numeric.h5","sint",scm,1,1)
/*
output:
        a	b	c	d	e	f	g
        '='	false	28	77	546	789	45
*/

请注意:数据集的 dataspace 维度必须小于等于 2。只有一维或二维表可以被解析。

loadPandasHDF5

语法

loadPandasHDF5(fileName,groupName,[schema],[startRow],[rowNum])

参数

fileName STRING 类型标量,由 Pandas 保存的 HDF5 文件名。

groupName STRING 类型标量,group 的标识符,即 key 名。

schema 包含列名和列的数据类型的表。若要改变由系统自动决定的列的数据类型,需要在 schema 表中修改数据类型,并且把它作为 loadPandasHDF5 函数的一个参数。

startRow INT 类型标量,从哪一行开始读取 HDF5 数据集。若不指定,默认从数据集起始位置读取。

rowNum INT 类型标量,读取 HDF5 数据集的行数。若不指定,默认读到数据集的结尾。

详情

将由 Pandas 保存的 HDF5 文件中的指定数据表加载为 DolphinDB 数据库的内存表。读取的行数为 HDF5 文件中定义的行数,而不是读取结果中的 DolphinDB 表的行数。支持的数据类型,以及数据转化规则可见数据类型章节。

例子

hdf5::loadPandasHDF5("../hdf5/h5file/data.h5","/s",,1,1)
/*
output:
        A	 B	C  D  E
        28 77	54 78 9
*/

loadHDF5Ex

语法

loadHDF5Ex(dbHandle, tableName, [partitionColumns], fileName, datasetName, [schema], [startRow], [rowNum], [transform])

参数

dbHandle 数据库句柄

tableName STRING 类型标量,表名。

partitionColumns 字符串标量或向量,表示分区列。当分区数据库不是 SEQ 分区时,我们需要指定分区列。在组合分区中,partitionColumns 是字符串向量。

fileName HDF5 文件名,类型为字符串标量。

datasetName dataset 名称,即表名,可通过 ls 或 lsTable 获得,类型为字符串标量。

schema 包含列名和列的数据类型的表。如果我们想要改变由系统自动决定的列的数据类型,需要在 schema 表中修改数据类型,并且把它作为loadHDF5Ex函数的一个参数。

startRow INT 类型标量,读取 HDF5 数据集的起始行位置。若不指定,默认从数据集起始位置读取。

rowNum INT 类型标量,读取 HDF5 数据集的行数。若不指定,默认读到数据集的结尾。

transform 一元函数,并且该函数接受的参数必须是一个表。如果指定了 transform 参数,需要先创建分区表,再加载数据,程序会对数据文件中的数据执行 transform 参数指定的函数,再将得到的结果保存到数据库中。

详情

将 HDF5 文件中的数据集转换为 DolphinDB 数据库的分布式表,然后将表的元数据加载到内存中。读取的行数为 HDF5 文件中定义的行数,而不是读取结果中的 DolphinDB 表的行数。支持的数据类型,以及数据转化规则可见数据类型章节。

例子

  • 磁盘上的 SEQ 分区表
db = database("seq_on_disk", SEQ, 16)
loadHDF5Ex(db,`tb,,"/large_file.h5", "large_table")
  • 内存中的 SEQ 分区表
db = database("", SEQ, 16)loadHDF5Ex(db,`tb,,"/large_file.h5", "large_table")
  • 磁盘上的非 SEQ 分区表
db = database("non_seq_on_disk", RANGE, 0 500 1000)
loadHDF5Ex(db,`tb,`col_4,"/smpl_numeric.h5","sint")
  • 内存中的非 SEQ 分区表
db = database("", RANGE, 0 500 1000)
t0 = loadHDF5Ex(db,`tb,`col_4,"/smpl_numeric.h5","sint")
  • 内存中的非 SEQ 分区表
db = database("", RANGE, 0 500 1000)
t0 = loadHDF5Ex(db,`tb,`col_4,"/smpl_numeric.h5","sint")
  • 指定 transform 将数值类型表示的日期和时间(比如:20200101)转化为指定类型(比如:日期类型)
dbPath="dfs://DolphinDBdatabase"
db=database(dbPath,VALUE,2020.01.01..2020.01.30)
dataFilePath="/transform.h5"
datasetName="/SZ000001/data"
schemaTB=hdf5::extractHDF5Schema(dataFilePath,datasetName)
update schemaTB set type="DATE" where name="trans_time"
tb=table(1:0,schemaTB.name,schemaTB.type)
tb1=db.createPartitionedTable(tb,`tb1,`trans_time);
def i2d(mutable t){
    return t.replaceColumn!(`trans_time,datetimeParse(string(t.trans_time),"yyyyMMdd"))
}
t = hdf5::loadHDF5Ex(db,`tb1,`trans_time,dataFilePath,datasetName,,,,i2d)

HDF5DS

语法

HDF5DS(fileName,datasetName,[schema],[dsNum])

参数

fileName STRING 类型标量,HDF5 文件名。

datasetName STRING 类型标量,数据集名,即表名。可通过lslsTable获得。

schema 包含列名和列的数据类型的表。若要改变由系统自动决定的列的数据类型,需要在 schema 表中修改数据类型,并且把它作为HDF5DS函数的一个参数。

dsNum INT 类型标量,需要生成的数据源数量。整个表会被均分为 dsNum 份。如果不指定,默认生成 1 个数据源。

详情

根据输入的文件名和数据集名创建数据源列表。

例子

ds = hdf5::HDF5DS(smpl_numeric.h5","sint")
size ds;
// output:1
ds[0];
// output:DataSource< loadHDF5("/smpl_numeric.h5", "sint", , 0, 3) >

ds = hdf5::HDF5DS(smpl_numeric.h5","sint",,3)
size ds;
// output:3
ds[0];
// output:DataSource< loadHDF5("/smpl_numeric.h5", "sint", , 0, 1) >
ds[1];
// output:DataSource< loadHDF5("/smpl_numeric.h5", "sint", , 1, 1) >
ds[2];
// output:DataSource< loadHDF5("/smpl_numeric.h5", "sint", , 2, 1) >

请注意:HDF5 不支持并行读入。以下例子是错误示范和正确示范

错误示范

ds = HDF5DS("/smpl_numeric.h5", "sint", ,3)
res = mr(ds, def(x) : x)

正确示范,将 mr parallel 参数设为 false

ds = HDF5DS("/smpl_numeric.h5", "sint", ,3)
res = mr(ds, def(x) : x,,,false)

saveHDF5

语法

saveHDF5(table, fileName, datasetName, [append], [stringMaxLength])

参数

table 要保存的内存表。

fileName HDF5 文件名,类型为字符串标量。

datasetName STRING 类型标量,dataset 名称,即表名。可通过 ls 或 lsTable 获得。

append BOOL 类型标量,默认为 false。是否追加数据到已存在 dataset。

stringMaxLength 字符串最大长度,类型为数值类型,默认为 16。仅对 table 中的 string 和 symbol 类型起作用。

详情

将 DolphinDB 数据库的内存表保存到 HDF5 文件中的指定数据集。支持的数据类型,以及数据转化规则可见数据类型章节。 注意,目前 HDF5 插件无法存储列数过多的表格,如果列数超过 900 列则有可能会存储失败。

例子

saveHDF5(tb, "example.h5", "dataset name in hdf5")

支持的数据类型

浮点和整数类型会被先转换为 H5T_NATIVE_*类型。

integer

Type in HDF5Default Value in HDF5Type in CType in DolphinDB
H5T_NATIVE_CHAR‘\0’signed char / unsigned charchar/short
H5T_NATIVE_SCHAR‘\0’signed charchar
H5T_NATIVE_UCHAR‘\0’unsigned charshort
H5T_NATIVE_SHORT0shortshort
H5T_NATIVE_USHORT0unsigned shortint
H5T_NATIVE_INT0intint
H5T_NATIVE_UINT0unsigned intlong
H5T_NATIVE_LONG0longint/long
H5T_NATIVE_ULONG0unsigned longunsupported/long
H5T_NATIVE_LLONG0long longlong
H5T_NATIVE_ULLONG0unsigned long longunsupported/long
  • DolphinDB 中数值类型都为有符号类型。为了防止溢出,除 64 位无符号类型外,所有无符号类型会被转化为高一阶的有符号类型。特别的,64 位无符号类型转化为 64 位有符号类型,若发生溢出则返回 64 位有符号类型的最大值。
  • H5T_NATIVE_CHAR 对应 C 中的 char 类型,而 char 是否有符号依赖与编译器及平台。若有符号依赖,则在 DolphinDB 中转化为 char,否则为 short。
  • H5T_NATIVE_LONG 以及 H5T_NATIVE_ULONG 对应 C 中的 long 类型。
  • 所有整数类型皆可以转化为 DolphinDB 中的数值类型(bool, char, short, int, long, float, double),若进行转化会发生溢出。例如 LONG->INT 会返回一个 int 的最值。

float

Type in HDF5Default Value in HDF5Type in CType in DolphinDB
H5T_NATIVE_FLOAT+0.0ffloatfloat
H5T_NATIVE_DOUBLE+0.0doubledouble

注意:IEEE754 浮点数类型皆为有符号数。

  • 所有浮点数类型皆可以转化为 DolphinDB 中的数值类型(bool, char, short, int, long, float, double),若进行转化会发生溢出。例如 DOUBLE->FLOAT 会返回一个 float 的最值。

time

type in hdf5Default Value in HDF5corresponding c typecorresponding dolphindb type
H5T_UNIX_D32BE1970.01.01T00:00:004 bytes integerDT_TIMESTAMP
H5T_UNIX_D32LE1970.01.01T00:00:004 bytes integerDT_TIMESTAMP
H5T_UNIX_D64BE1970.01.01T00:00:00.0008 bytes integerDT_TIMESTAMP
H5T_UNIX_D64LE1970.01.01T00:00:00.0008 bytes integerDT_TIMESTAMP
  • HDF5 预定义的时间类型为 32 位或者 64 位的 posix 时间。HDF5 的时间类型缺乏官方的定义,在此插件中,32 位时间类型代表距离 1970 年的秒数,而 64 位则精确到毫秒。所有时间类型会被插件统一转化为一个 64 位整数,然后转化为 DolphinDB 中的 timestamp 类型。
  • 以上类型皆可以转化为 DolphinDB 中的时间相关类型(date, month, time, minute, second, datetime, timestamp, nanotime, nanotimestamp)。

string

type in hdf5Default Value in HDF5corresponding c typecorresponding dolphindb type
H5T_C_S1“”char*DT_STRING
  • H5T_C_S1 包括固定长度(fixed-length)字符串和可变长度(variable-length)字符串。
  • string 类型可以转化为 DolphinDB 中的字符串相关类型(string, symbol)。

enum

type in hdf5corresponding c typecorresponding dolphindb type
ENUMenumDT_SYMBOL
  • 枚举类型会被转化为 DolphinDB 中的一个 symbol 变量。请注意,每个字符串所对应的枚举值以及大小关系并不会被保存。例如,枚举类型 HDF5_ENUM{"a"=100,"b"=2000,"c"=30000}可能会被转化为 SYMBOL{"a"=3,"b"=1"c"=2}。
  • enum 类型可以转化为 DolphinDB 中的字符串相关类型(string, symbol)。

compound and array

type in hdf5corresponding c typecorresponding dolphindb type
H5T_COMPOUNDstruct\
H5T_ARRAYarray\
  • 复合(compound)类型以及数组(array)类型只要不包含不支持的类型,就可以被解析,而且支持嵌套。
  • 复杂类型的转化取决于其内部子类型。

表结构

简单类型

简单类型导入 DolphinDB 后的 table 与 HDF5 文件中的 table 完全一致。

HDF5 中的简单类型表

12
1int(10)int(67)
2int(20)int(76)

导入 DolphinDB 后的简单类型表

col_1col_2
11067
22076

复杂类型

复杂类型导入 DolphinDB 后的类型取决于复杂类型的结构。

HDF5 中的复合类型表

12
1structstruct
2structstruct

导入 DolphinDB 后:

abc
1123.7
2112131.7
3122232.7
4132333.7

HDF5 中的数组类型表

12
1array(1,2,3)array(4,5,6)
2array(8,9,10)array(15,16,17)

导入 DolphinDB 后:

array_1array_2array_3
1123
2456
38910
4151617

HDF5 中的嵌套类型表

对嵌套的复杂类型,结果中会添加'A'前缀代表数组,'C'前缀代表复合类型。

12
1struct{a:array(1,2,3) b:2 c:struct{d:"abc"}}struct{a:array(7,8,9) b:5 c:struct{d:"def"}}
2struct{a:array(11,21,31) b:0 c:struct{d:"opq"}}struct{a:array(51,52,53) b:24 c:struct{d:"hjk"}}

导入 DolphinDB 后:

Aa_1Aa_2Aa_3bCc_d
11232abc
27895def
31121310opq
451525324hjk

性能

环境

  • CPU: i7-7700 3.60GHZ
  • SSD: 连续读取 最多每秒 460~500MB

数据集导入性能

  • 单一类型(int)
    • 行数 1024 * 1024 * 16
    • 列数 64
    • 文件大小 4G
    • 耗时 8 秒
  • 单一类型(unsigned int)
    • 行数 1024 * 1024 * 16
    • 列数 64
    • 文件大小 4G
    • 耗时 9 秒
  • 单一类型(variable-length string)
    • 行数 1024 * 1024
    • 列数 64
    • 文件大小 3.6G
    • 耗时 17 秒
  • 复合类型
    • 子类型共 9 列:(str,str,double,int,long,float,int,short,char)
    • 行数 1024 * 1024 * 62
    • 文件大小 3.9G
    • 耗时 10 秒
  • 数组复合类型
    • 子类型共 72 列:(str,str,double,int,long,float,int,short,char) * 8
    • 行数 1024 * 128 * 62
    • 文件大小 3.9G
    • 耗时 15 秒