【问题标题】:Recommended way for child-parent relationship in pytablespytables中子父关系的推荐方式
【发布时间】:2021-11-23 14:15:52
【问题描述】:

我正在使用 pytables,并且正在尝试实现父子关系。例如,我想存储多支球队,每支球队都有多名球员。我可以通过以下方式做到这一点:

import tables as tb



class Team(tb.IsDescription):
    id = tb.Int32Col() #Id of team
    name = tb.StringCol(20) #Name of team


class Player(tb.IsDescription):
    team = tb.Int32Col() #Link to team::team_id
    name = tb.StringCol(20) #Name of player

f = tb.open_file('test.h5',mode='w',title='test')
table_team = f.create_table(f.root,'teams',Team)
table_player = f.create_table(f.root,'players',Player)

team = table_team.row
team['id'] = 0
team['name'] = 'Barcelona'
team.append()

player0 = table_player.row
player0['team'] = 0
player0['name'] = 'De Jong'
player0.append()

player1 = table_player.row
player1['team'] = 0
player1['name'] = 'Fati'
player1.append()

f.close()

但是,pytables 文档对此做了以下说明 (https://www.pytables.org/cookbook/hints_for_sql_users.html):

"你可能已经注意到 PyTables 中的查询只覆盖一张表。 事实上,没有办法直接在两个之间执行连接 PyTables 中的表(请记住,它不是关系数据库)。”

然后它继续为连接查询提供一些解决方法。但是,正如他们所说,pytables 不是关系数据库。因此,我没有使用基于关系的方法和解决方法,而是提出以下问题:

在 pytables 中实现父子结构的推荐/标准方法是什么?

【问题讨论】:

  • 你需要对他们做什么
  • @ScottHunter 对于我目前正在处理的情况,它只是存储值并稍后绘制它们。基本上,父节点是一个实验,子节点是数据点,会定期添加。

标签: python parent-child pytables


【解决方案1】:

您的用例是否需要父子关系?我认为 HDF5 分层数据结构将组织您的实验数据。为每个实验创建一个不同的表,将行作为数据点。实验元数据作为属性存储在每个表上。

我创建了一个带有“虚拟数据”的简单示例来演示此架构。

注意:为简单起见,我更喜欢使用 NumPy 来创建表格。首先,我创建一个数据类型 (exp_dt),然后使用它创建基线“实验数据”作为 NumPy recarrry (exp_arr)。表数据是通过修改exp_arr中的时间和压力值来创建第二个数组(data)。我使用obj=data 参数将data 加载到每个表中。该示例可以修改为创建class Experiment(tb.IsDescription)并逐行加载数据。

代码如下:

# define table structure with NumPy dtype
exp_dt = np.dtype( [ ('Time',float),('Temp',float),('Pres',float) ] )

# create baseline dummy data (used later)
exp_arr = np.empty(shape=(11,), dtype=exp_dt)
for i in range(11):
    exp_arr[i]['Time'] = i/10.
    exp_arr[i]['Temp'] = i**2/10.
    exp_arr[i]['Pres'] = 2.*i

# create empty recarray; used to load experimental data
data = np.empty(shape=(11,), dtype=exp_dt)

# create some metadata for experiment date, time and device
date_list = ['11/17/2021','11/19/2021','11/23/2021']
time_list = ['10:49:23', '08:14:25', '14:40:23' ]
device_list = ['Hex 6500', 'Hex 4414', 'CMM 6950']
        
with tb.File('SO_70082470.h5','w') as h5f:
    for i in range(1,4):
        # create dummy data for THIS experiment
        data['Time'] = exp_arr['Time']
        data['Temp'] = exp_arr['Temp'] + i
        data['Pres'] = exp_arr['Pres'] + 2.*i
        # create table and load data
        tbl = h5f.create_table('/', f'Experiment_{i:03}', obj=data)
        # add 3 attributes: Date, Time and Device:
        tbl.attrs['Date'] = date_list[i-1]
        tbl.attrs['Time'] = time_list[i-1]
        tbl.attrs['Device'] = device_list[i-1]

【讨论】:

  • 是的,可能我需要改变我的思维方式,远离关系方法。您的方法似乎是做到这一点的好方法。但是,我唯一缺少的是某种存储有关实验的元数据的方法。我可以添加一个表格“实验”,但我也愿意接受其他想法。
  • HDF5(和 PyTables)使用属性来存储元数据。属性/元数据可以是任何类型的数据——字符串、整数、浮点数,甚至是数组。我修改了上面的例子来展示如何添加 3 个属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-10
  • 1970-01-01
相关资源
最近更新 更多