在Python中(使用pytables),可以很容易地创建包含时间戳的行的HDF5表(列数据类型为Time64
,请参阅http://pytables.github.io/usersguide/datatypes.html)。
是否可以读取包含IDL 8.2中类型为Time64的列的表?
的默认方法fid = H5F_OPEN(filename)
tabID = H5D_OPEN(fid, '/path/to/table')
data = H5D_READ(tabID)
如果节点/path/to/table
包含Time64类型的列,则似乎会阻塞。我想在IDL中有一种转换/解释数据类型的方法,即使IDL本身不支持它,或者不支持?毕竟,Time64列只是8个字节的值......
我能找到的最相关的IDL文档是http://www.exelisvis.com/docs/HDF5_Overview.html。
作为一个侧面问题:来自HDF5组的HDFView似乎也不支持Time64,尽管HDF5中存在一种特殊的8字节列类型(对不起,我不允许发布另一个链接)。 pytables使用的这种列类型是不是标准的列类型?
编辑:我创建了一个包含带有Time64列的表的示例性hdf5文件,请参阅链接的注释。该文件是使用以下Python代码创建的:
import tables as T
import time
exampleTableColumns = {
'id': T.Int32Col(pos=0),
'value': T.Float32Col(pos=1),
'timestamp': T.Time64Col(pos=2),
}
with T.openFile('time64-example.h5', 'w') as h5:
exampleTab = h5.createTable(
'/', 'example', exampleTableColumns)
# Add some test values
t = time.time()
for i in range(10):
exampleTab.row['id'] = i
exampleTab.row['value'] = i**2
exampleTab.row['timestamp'] = t + 0.5*i
exampleTab.row.append()
exampleTab.flush()
我尝试从IDL读取它是:
fid = h5f_open(filename)
exampleTab = H5D_OPEN(fid, '/example')
; id: 32 bit signed integer, value: float32, timestamp: 8 byte value
struct = {id:0L, value:0.0, timestamp:0LL}
dt = H5T_IDL_CREATE(struct)
exampleData = H5D_READ(exampleTab, dt)
print, 'exampleData.id:', exampleData.id
print, 'exampleData.value', exampleData.value
print, 'exampleData.timestamp', exampleData.timestamp
h5d_close, exampleTab
h5f_close, fid
H5D_READ
在获得自定义数据类型后不会再次阻塞,但id
和value
字段中的值已经出现乱码。这是我从print语句得到的输出:
exampleData.id: 0 0 0 1095914052 174536304 153749104 0 172915600 1095914052 910565433
exampleData.value 0.000000 0.000000 0.000000 13.1451 0.000000 0.000000 0.000000 0.000000 13.1451 640.894
exampleData.timestamp 0 0 0 3833484811918717440 5858206660165639 153997792
5858318295760901 154274128 4051322254670378805 5858331130331138
如果我将struct
更改为(我相信的等效定义)struct = {id:lonarr(1), value:0.0, timestamp:0LL}
,则打印语句会产生:
exampleData.id: 262404320 3 262404416 4 262404512 14 0 172915600 1095914052 910565433
exampleData.value 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 13.1451 640.894
exampleData.timestamp 0 0 0 3833484811918717440 0 153997568
5858318295760901 154274128 4051322254670378805 791781549539330
答案 0 :(得分:0)
我已经想出如何从数据文件中读取timestamp
列。其中涉及阅读PyTables的来源。
看起来该列实际上是作为HDF5类型H5T_UNIX_D64LE
编写的。还有一些比特转移。
以下(rtbl.py
)是用于转储文件time64-example.h5
的python版本:
#!/usr/env/bin python
import tables as T
import time
exampleTableColumns = {
'id': T.Int32Col(pos=0),
'value': T.Float32Col(pos=1),
'timestamp': T.Time64Col(pos=2),
}
with T.openFile('time64-example.h5', 'r') as h5:
for row in h5.root.example[:]:
print "%d\t%.2f\t%s" %(row['id'], row['value'],
time.ctime(row['timestamp']))
运行这个我们可以得到以下结果:
$ env TZ=UTC ./rtbl.py
0 0.00 Wed Apr 9 08:56:24 2014
1 1.00 Wed Apr 9 08:56:25 2014
2 4.00 Wed Apr 9 08:56:25 2014
3 9.00 Wed Apr 9 08:56:26 2014
4 16.00 Wed Apr 9 08:56:26 2014
5 25.00 Wed Apr 9 08:56:27 2014
6 36.00 Wed Apr 9 08:56:27 2014
7 49.00 Wed Apr 9 08:56:28 2014
8 64.00 Wed Apr 9 08:56:28 2014
9 81.00 Wed Apr 9 08:56:29 2014
然后在C(rtbl.c
)中做同样的事情 - 请原谅所有硬编码并且没有错误检查。
#include <stdlib.h>
#include <stdio.h>
#include <hdf5.h>
#include <time.h>
struct row {
int id;
float value;
double time;
};
double
convert(double d) {
union {
double d;
long long i;
} di;
double f;
di.d = d;
f = 1e-6 * (int)di.i + (di.i >> 32);
return f;
}
int
main(int argc, char **argv)
{
hid_t f_id;
hid_t d_id;
hid_t m_type;
herr_t err;
int i = 0;
struct row rows[10] = {0};
time_t clock;
f_id = H5Fopen("time64-example.h5", H5F_ACC_RDONLY, H5P_DEFAULT);
m_type = H5Tcreate(H5T_COMPOUND, sizeof(struct row));
err = H5Tinsert(m_type, "id", HOFFSET(struct row, id),
H5T_STD_I32LE);
err = H5Tinsert(m_type, "value", HOFFSET(struct row, value),
H5T_IEEE_F32LE);
err = H5Tinsert(m_type, "timestamp", HOFFSET(struct row, time),
H5T_UNIX_D64LE);
d_id = H5Dopen(f_id, "example", H5P_DEFAULT);
err = H5Dread(d_id, m_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, rows);
for (i = 0; i < 10; ++i) {
clock = (time_t)convert(rows[i].time);
printf("%d: %d\t%.2f\t%s", i,
rows[i].id, rows[i].value, ctime(&clock));
}
H5Dclose(d_id);
H5Fclose(f_id);
return(EXIT_SUCCESS);
}
这会产生相同的结果:
$ h5cc -o rtbl rtbl.c && env TZ=UTC ./rtbl
0 0.00 Wed Apr 9 08:56:24 2014
1 1.00 Wed Apr 9 08:56:25 2014
2 4.00 Wed Apr 9 08:56:25 2014
3 9.00 Wed Apr 9 08:56:26 2014
4 16.00 Wed Apr 9 08:56:26 2014
5 25.00 Wed Apr 9 08:56:27 2014
6 36.00 Wed Apr 9 08:56:27 2014
7 49.00 Wed Apr 9 08:56:28 2014
8 64.00 Wed Apr 9 08:56:28 2014
9 81.00 Wed Apr 9 08:56:29 2014
所以这一切都回到了convert
例程和H5T_UNIX_D64LE
。我敢说,如果在大端上完成任何一项,那么LE
应该是BE
。
对不起,自从我使用IDL并且无法访问它以来已经有好几年了,但我希望这会有所帮助。