为带有类型项目的字典优化的容器?

时间:2019-05-03 06:40:55

标签: python python-3.x numpy

我从数据集中得到一个大型(类型化)数组,第一列包含用于索引每一行的唯一键,其他列包含已知大小的矩阵或向量。我有什么标准的方法或库可以有效地将其转换为哈希图,以便进行基于键的检索?将行拆分为单独的键值对象似乎并不十分节省内存。

这是基准次优解决方案:

arr = np.array([
    ('b0263', 'a', 1, 2, 3),
    ('26ab0', 'b', 4, 5, 6),
    ('6d7fc', 'c', 7, 8, 9),
    ('48a24', 'd', 0, 1, 2),
    ('1dcca', 'e', 3, 4, 5)],
    dtype="S5, c, i4, i4, i4")
out = {key: values for key, *values in arr}

我想过一个字典,其中包含相应行的整数索引,但是它需要两个索引级别。

1 个答案:

答案 0 :(得分:0)

您的结构化数组:

In [317]: arr                                                                        
Out[317]: 
array([(b'b0263', b'a', 1, 2, 3), (b'26ab0', b'b', 4, 5, 6),
       (b'6d7fc', b'c', 7, 8, 9), (b'48a24', b'd', 0, 1, 2),
       (b'1dcca', b'e', 3, 4, 5)],
      dtype=[('f0', 'S5'), ('f1', 'S1'), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<i4')])

第一个字段:

In [318]: arr['f0']                                                                  
Out[318]: array([b'b0263', b'26ab0', b'6d7fc', b'48a24', b'1dcca'], dtype='|S5')

从该数组构建的字典:

In [321]: dd = {k:v for k,v in zip(arr['f0'], arr)}                                  
In [322]: dd                                                                         
Out[322]: 
{b'b0263': (b'b0263', b'a', 1, 2, 3),
 b'26ab0': (b'26ab0', b'b', 4, 5, 6),
 b'6d7fc': (b'6d7fc', b'c', 7, 8, 9),
 b'48a24': (b'48a24', b'd', 0, 1, 2),
 b'1dcca': (b'1dcca', b'e', 3, 4, 5)}
In [323]: dd[b'6d7fc']                                                               
Out[323]: (b'6d7fc', b'c', 7, 8, 9)

在这种结构中,字典元素的值是原始数组的元素。

它具有type np.voiddtype

In [329]: dd[b'6d7fc'].dtype                                                         
Out[329]: dtype([('f0', 'S5'), ('f1', 'S1'), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<i4')])

它实际上是原始文件的view(我检查过__array_interface__)。因此,除了指针/引用外,它不会消耗太多额外的内存。

最近的numpy版本正在重新构造结构化数组的视图/副本,因此细节可能已经更改,尤其是在多字段引用方面。

我应该限定记忆注释。在此示例中,itemsize只有18。但是arr[0]引用数组的元素会创建一个新的np.void对象。我怀疑对象开销大于18个字节。

您可以使用元组值创建字典:

In [335]: dd = {k:v.tolist()[1:] for k,v in zip(arr['f0'], arr)}                     
In [336]: dd[b'b0263']                                                               
Out[336]: (b'a', 1, 2, 3)