在pytables中设置类型

2024-09-30 04:34:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下形式的数据:

"blue red"
"blue magenta cyan"
"yellow red"
"black" 

每行的最大元素数是10,但是可以有数千个标签/类别/颜色。我想以某种方式在pytables列中插入此数据,以便以以下形式进行查询:

^{pr2}$

例如,返回包含blue标签的所有文档(结果将是前两行)。鉴于Pytables没有set数据类型,实现这一点的最有效方法是什么?在


Tags: 数据元素颜色方式bluered标签pytables
1条回答
网友
1楼 · 发布于 2024-09-30 04:34:03

你只有maxN=10这个事实很好。这意味着进行这种比较是可能的。你应该做的是有10个字符串列,每列是一个标签。如果一行的标签少于10个,则用空白字符串填充。在

这将允许您编写高效的查询表达式,可以在Table.where()Table.read_where()命令[1]中使用。假设列有愚蠢的名称“col0”、“col1”等。因为字符串比较在numexpr中是精确的,并且没有本机集类型,因此必须显式展开相等比较:

cond = ("col0 == 'blue' | col1 == 'blue' | col2 == 'blue' | col3 == 'blue' | "
        "col4 == 'blue' | col5 == 'blue' | col6 == 'blue' | col7 == 'blue' | "
        "col8 == 'blue' | col9 == 'blue'")
rows = [row[:] for row in table.where(cond)]

幸运的是,编程构造cond字符串很容易:

^{pr2}$

然而,你还可以做更多的事情。字符串比较是庞大而缓慢的。这是因为所有的字符串都必须具有相同的大小,这意味着列大小由最长的标签决定。这会导致大量的空间浪费。相反,您应该有一个与标签整数的映射。然后你就可以存储这些整数,很快地对它们进行比较。例如,使用列表索引:

labels = ['', 'blue', 'red', 'yellow', ...]
labels_to_idx = dict(zip(labels, range(len(labels))))
cond = " | ".join(["col{0} == '{1}'".format(i, labels_to_idx['blue']) 
                   for i in range(10)])
rows = [[labels[x] for x in row[:]] for row in table.where(cond)]

您甚至可以将标签列表存储在PyTables中作为一个array,这样您就可以确保始终获得相同的索引顺序,同时还可以扩展allow labels的列表。在

此外,由于标签将被重用,特别是空字符串标签,我强烈建议您启用压缩。在

不幸的是,由于列是索引的(不是表),所以不能为这些查询编制索引。在

通过压缩和映射到整数/从整数映射,这可能是最快和最小的。在

  1. http://pytables.github.io/usersguide/libref/structured_storage.html?highlight=read_where#tables.Table.read_where

相关问题 更多 >

    热门问题