pytables 添加重复子类作为列
pytables add repetitive subclass as column
我正在创建一个具有严格参数的 HDF5 文件。它有 1 table 个由可变列组成的。在某一时刻,这些列随着附加的不同数据而变得重复。显然,我无法在 IsDescription class 内添加循环。目前 class 段已在 class Summary_data 下添加了两次。我需要调用 segments_k 70 次。最好的方法是什么?谢谢。
class Header(IsDescription):
_v_pos = 1
id = Int16Col(dflt=1, pos = 0)
timestamp = Int16Col(dflt=1, pos = 1)
class Segments(IsDescription):
segment_id = Int16Col(dflt=1, pos = 0)
segment_quality = Float32Col(dflt=1, pos = 1)
segment_length = Float32Col(dflt=1, pos = 2)
class Summary_data(IsDescription):
latency = Float32Col(dflt=1, pos = 2)
segments_k = Int16Col(dflt=1, pos = 4)
segments_k0 = Segments()
segments_k1 = Segments()
class Everything(IsDescription):
header = Header()
summary_data = Summary_data()
def write_new_file():
h5file = "results.hdf5"
with open_file(h5file, mode = "w") as f:
root = f.root
table1 = f.create_table(root, "Table1", Everything)
row = table1.row
length = [[23.5, 16.3], [8, 6]]
quality = [[0.9, 0.7], [0.6, 0.4]]
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(2):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
抱歉,我没有听懂您在评论中的解释。下面是来自 HDFView 的屏幕截图,显示了 schema/table 布局。在我看来,segments_k0{0}
和 segments_k1{0}
嵌套在 summary_data
下。
查看它如何显示 summary_data->segments_k0{0}
。那是你要的吗? 70 个嵌套列,每个列有 3 个嵌套列(segment_id
、segment_quality
和 segment_length
)?
或者,您只想将 segments_k0{0}
嵌套在 0
行下。?
我使用该架构创建了第二个 table (Table2)。请参阅下面的屏幕截图。
请注意 segments_k0{0}
前面没有 summary_data->
(它不是嵌套的)。
当您使用 np.dtype()
输入描述时,这两种情况都可能发生。您可以使用字典定义数据类型并以编程方式填充字段名称和格式。第二个 table 更容易定义。在向您展示如何创建 np.dtype()
.
之前,我想确定您想要哪个
好的,我想我明白了,我将尝试解释我是如何做到这一点的(以及如何扩展以处理所有 70 个段)。顺便说一句,您的嵌套字段非常复杂,比我见过的任何东西都复杂得多。您确定需要这么多级别的嵌套字段吗?
关键是使用 np.dtype()
来定义 table 描述。我总是使用它们来定义我的 tables,而不是 IsDescription
方法。 (我使用 NumPy 来处理我的 HDF5 数据,所以我对这个模块很满意table。)在你的情况下,你需要一个 dytpe,因为这是我知道的创建复杂 table 的唯一方法结构与代码。否则,您将花费数小时创建 IsDescription
个整体。 :-)
下面的代码使用 3 种不同的方法来创建 3 个 table(每个 table 中的架构和数据应该相同)。每个的解释:
- Table 1:是用您的代码创建的。它使用
IsDescription
方法创建 3
summary_data/segments_k#
个条目。 (我将 segments_k2 = Segments()
添加到 class Summary_data()
)。注意这行代码:
print (tb.description.dtype_from_descr(Everything) )
。它打印
Table1 使用的 Everything
描述的等效 np.dtype。
我在下面的 Tables 2 和 3 中引用了这个。
- Table 2 描述引用 np.dtype
tb2_dt
。我 copied/pasted
这来自之前的输出。我可以引用为变量,
但我希望您看到它以了解我为 Table 所做的工作 3. 填充 table 的代码与 Table 1. 相同
- Table 3 描述引用 np.dtype
tb3_dt
。这就是事情变得棘手的地方。 np.dtype 结构很复杂:它是元组的列表和列表的元组。 dtype 是从 seg_kn_list
和 tb3_dt_list
构建的。填充 table 的代码与 Table 1 和 2. 相同
要使其适用于 70 个段,您“所有”要做的就是更改创建 seg_kn_tlist
的 2 个 range(3)
参数并填充数据行。 (当然,你也需要提供数据。)
代码如下:
import tables as tb
import numpy as np
h5file = "SO_64449277np.h5"
with tb.open_file(h5file, mode = "w") as h5f:
length = [[23.5, 16.3], [8, 6], [11.0, 7.7]]
quality = [[0.9, 0.7], [0.6, 0.4], [0.8, 0.5]]
root = h5f.root
table1 = h5f.create_table(root, "Table1", Everything)
print (tb.description.dtype_from_descr(Everything) )
row = table1.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
tb2_dt = np.dtype([('header', [('id', '<i2'), ('timestamp', '<i2')]),
('summary_data', [('latency', '<f4'), ('segments_k', '<i2'),
('segments_k0', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
('segments_k1', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
('segments_k2', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
])] )
table2 = h5f.create_table(root, "Table2", tb2_dt)
row = table2.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
# Create np.dtype() iteratively
# Start with laency and segments_k, and use a loop to add segments_k# id, quality and length
seg_kn_tlist = [('latency', '<f4'), ('segments_k', '<i2') ]
for cnt in range(3) :
seg_kn_tlist.append( ('segments_k'+str(cnt),
[('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')] ) )
# Finish np.dtype() definition with fileds for header, timestamp and summary_data, followed by tuple with list above
tb3_dt_list = [ ('header', [('id', '<i2'), ('timestamp', '<i2')]), ('summary_data', seg_kn_tlist) ]
tb3_dt = np.dtype( tb3_dt_list )
table3 = h5f.create_table(root, "Table3", tb3_dt)
row = table3.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
我正在创建一个具有严格参数的 HDF5 文件。它有 1 table 个由可变列组成的。在某一时刻,这些列随着附加的不同数据而变得重复。显然,我无法在 IsDescription class 内添加循环。目前 class 段已在 class Summary_data 下添加了两次。我需要调用 segments_k 70 次。最好的方法是什么?谢谢。
class Header(IsDescription):
_v_pos = 1
id = Int16Col(dflt=1, pos = 0)
timestamp = Int16Col(dflt=1, pos = 1)
class Segments(IsDescription):
segment_id = Int16Col(dflt=1, pos = 0)
segment_quality = Float32Col(dflt=1, pos = 1)
segment_length = Float32Col(dflt=1, pos = 2)
class Summary_data(IsDescription):
latency = Float32Col(dflt=1, pos = 2)
segments_k = Int16Col(dflt=1, pos = 4)
segments_k0 = Segments()
segments_k1 = Segments()
class Everything(IsDescription):
header = Header()
summary_data = Summary_data()
def write_new_file():
h5file = "results.hdf5"
with open_file(h5file, mode = "w") as f:
root = f.root
table1 = f.create_table(root, "Table1", Everything)
row = table1.row
length = [[23.5, 16.3], [8, 6]]
quality = [[0.9, 0.7], [0.6, 0.4]]
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(2):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
抱歉,我没有听懂您在评论中的解释。下面是来自 HDFView 的屏幕截图,显示了 schema/table 布局。在我看来,segments_k0{0}
和 segments_k1{0}
嵌套在 summary_data
下。
查看它如何显示 summary_data->segments_k0{0}
。那是你要的吗? 70 个嵌套列,每个列有 3 个嵌套列(segment_id
、segment_quality
和 segment_length
)?
或者,您只想将 segments_k0{0}
嵌套在 0
行下。?
我使用该架构创建了第二个 table (Table2)。请参阅下面的屏幕截图。
请注意 segments_k0{0}
前面没有 summary_data->
(它不是嵌套的)。
当您使用 np.dtype()
输入描述时,这两种情况都可能发生。您可以使用字典定义数据类型并以编程方式填充字段名称和格式。第二个 table 更容易定义。在向您展示如何创建 np.dtype()
.
好的,我想我明白了,我将尝试解释我是如何做到这一点的(以及如何扩展以处理所有 70 个段)。顺便说一句,您的嵌套字段非常复杂,比我见过的任何东西都复杂得多。您确定需要这么多级别的嵌套字段吗?
关键是使用 np.dtype()
来定义 table 描述。我总是使用它们来定义我的 tables,而不是 IsDescription
方法。 (我使用 NumPy 来处理我的 HDF5 数据,所以我对这个模块很满意table。)在你的情况下,你需要一个 dytpe,因为这是我知道的创建复杂 table 的唯一方法结构与代码。否则,您将花费数小时创建 IsDescription
个整体。 :-)
下面的代码使用 3 种不同的方法来创建 3 个 table(每个 table 中的架构和数据应该相同)。每个的解释:
- Table 1:是用您的代码创建的。它使用
IsDescription
方法创建 3summary_data/segments_k#
个条目。 (我将segments_k2 = Segments()
添加到class Summary_data()
)。注意这行代码:print (tb.description.dtype_from_descr(Everything) )
。它打印 Table1 使用的Everything
描述的等效 np.dtype。 我在下面的 Tables 2 和 3 中引用了这个。 - Table 2 描述引用 np.dtype
tb2_dt
。我 copied/pasted 这来自之前的输出。我可以引用为变量, 但我希望您看到它以了解我为 Table 所做的工作 3. 填充 table 的代码与 Table 1. 相同
- Table 3 描述引用 np.dtype
tb3_dt
。这就是事情变得棘手的地方。 np.dtype 结构很复杂:它是元组的列表和列表的元组。 dtype 是从seg_kn_list
和tb3_dt_list
构建的。填充 table 的代码与 Table 1 和 2. 相同
要使其适用于 70 个段,您“所有”要做的就是更改创建 seg_kn_tlist
的 2 个 range(3)
参数并填充数据行。 (当然,你也需要提供数据。)
代码如下:
import tables as tb
import numpy as np
h5file = "SO_64449277np.h5"
with tb.open_file(h5file, mode = "w") as h5f:
length = [[23.5, 16.3], [8, 6], [11.0, 7.7]]
quality = [[0.9, 0.7], [0.6, 0.4], [0.8, 0.5]]
root = h5f.root
table1 = h5f.create_table(root, "Table1", Everything)
print (tb.description.dtype_from_descr(Everything) )
row = table1.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
tb2_dt = np.dtype([('header', [('id', '<i2'), ('timestamp', '<i2')]),
('summary_data', [('latency', '<f4'), ('segments_k', '<i2'),
('segments_k0', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
('segments_k1', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
('segments_k2', [('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')]),
])] )
table2 = h5f.create_table(root, "Table2", tb2_dt)
row = table2.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()
# Create np.dtype() iteratively
# Start with laency and segments_k, and use a loop to add segments_k# id, quality and length
seg_kn_tlist = [('latency', '<f4'), ('segments_k', '<i2') ]
for cnt in range(3) :
seg_kn_tlist.append( ('segments_k'+str(cnt),
[('segment_id', '<i2'), ('segment_quality', '<f4'), ('segment_length', '<f4')] ) )
# Finish np.dtype() definition with fileds for header, timestamp and summary_data, followed by tuple with list above
tb3_dt_list = [ ('header', [('id', '<i2'), ('timestamp', '<i2')]), ('summary_data', seg_kn_tlist) ]
tb3_dt = np.dtype( tb3_dt_list )
table3 = h5f.create_table(root, "Table3", tb3_dt)
row = table3.row
for i in range(2):
row['header/id'] = i
row['header/timestamp'] = i * 2.
row['summary_data/latency'] = 0.0
row['summary_data/segments_k'] = 0
for data in range(3):
row['summary_data/segments_k'+str(data)+'/segment_id'] = data
row['summary_data/segments_k'+str(data)+'/segment_quality'] = quality[data][i]
row['summary_data/segments_k'+str(data)+'/segment_length'] = length[data][i]
row.append()