我正在寻找一种有效的解决方案,使用 numpy 和 arrow 等高级优化数学包在 Python 中构建二级内存索引。出于性能原因,我不包括熊猫。
定义
“二级索引包含要索引的属性的每个现有值的条目。这个条目可以看作是一个键/值对,属性值为键,值是指向基表中所有记录的指针列表有这个价值。” -合资企业。德席尔瓦等人。(2017)
让我们举一个简单的例子,我们可以稍后对其进行扩展以产生一些基准:
import numpy as np
pk = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='uint32')
val = np.array([15.5, 3.75, 142.88, 142.88, None, None, None, 7.2, 2.1], dtype='float32')
有趣的是pyarrow.Array.dictionary_encode方法可以将值数组转换为接近二级索引的字典编码表示。
val.dictionary_encode()
Out[55]:
<pyarrow.lib.DictionaryArray object at 0x7ff430d8b4d0>
-- dictionary:
[
15.5,
3.75,
142.88,
nan,
7.2,
2.1
]
-- indices:
[
0,
1,
2,
2,
3,
3,
3,
4,
5
]
因此,问题在于您可以多快地使用 Python 数据结构在内存中构建二级索引以有效地保存值和索引。但这只是故事的一半,因为如果索引能够很好地服务于过滤查询(点、范围)和转换——在TRIADB中重建行、列和关联(也称为超边),它就会很有用。甚至这里的快速描述也没有涵盖更新这种索引有多么容易。
出于多种原因,我开始研究可能的 PyArrow 开源解决方案。排序后的字典编码表示通常应该满足问题的要求,并结合了更小的内存占用和更快/灵活的零拷贝 I/O 处理。