繁体   English   中英

有人知道Python中一个很好的稀疏一维数组库吗?

[英]Anyone Know a Great Sparse One Dimensional Array Library in Python?

我正在研究一种使用int64s数组的算法。 这些数组通常是稀疏的,并且不断地读取和写入。 我目前正在使用相对较大的本机阵列,性能良好,但内存使用率很高(正如预期的那样)。

我希望能够让数组实现不浪费空间用于未使用的值,并允许索引偏移量不为零。 举个例子,如果我的数字从1,000,000开始,我希望能够从1,000,000开始索引我的数组,并且不需要浪费具有一百万个未使用值的内存。

数组读取和写入需要很快。 扩展到新领域可能会有一点延迟,但如果可能,读取和写入应为O(1)。

有人知道可以做到的图书馆吗?

谢谢!

更新为提及int64作为数据类型。

这听起来像blist类型( 文档下载 )可能正是你正在寻找的(免责声明:我是作者)。 它具有与Python list完全相同的界面,因此没有学习曲线,但它具有不同的性能特征。 特别是,在许多情况下,它可以有效地处理稀疏列表。 下面是一个创建包含2 ** 29个元素的列表的示例。 这几乎是瞬间完成的。 以这种方式创建的稀疏列表使用O(log n)空间。

>>> from blist import *
>>> x = blist([0])             # x is a blist with one element
>>> x *= 2**29                 # x is a blist with > 500 million elements
>>> x.append(5)                # append to x
>>> y = x[4:-234234]           # Take a 500 million element slice from x
>>> del x[3:1024]              # Delete a few thousand elements from x

迭代整个列表的操作仍需要O(n)时间( removereversecount等)。 文档说明了每个操作的时间复杂性,因此您应该能够评估它是否满足您的需求。

您可以将numpy稀疏矩阵重新映射到稀疏数组中 - 或者考虑使用哈希表(python dict)。 就偏移量而言,只需包装您正在使用的任何存储类,并使您拥有自己的插入/查找/删除方法。

我不知道任何Python,所以这可能是一个没有答案:

在某些语言中,您可以通过将索引空间中的函数定义到数据空间来模拟稀疏数组。 例如(伪代码):

f[1000000] = 32;
f[2000000] = 51;

在某些语言(最好的语言)中,数组引用的形式(例如f[3] )看起来就像函数调用的形式(例如f[3] )。 当然,这是因为数组定义了从索引空间到数据空间的函数。 以这种方式实现更高维度的稀疏数组也非常容易。

为什么不用dict?

sparse = dict()
sparse[100000] = 1234
sparse[123456] = 2345

另一个选择 - 至少如果你愿意自己实现一个 - 是一个Page表 这通常用于虚拟内存系统中,以将虚拟地址映射到物理地址,如果地址空间稀疏填充,并且使用的地址是群集的,则效果最佳。 如果使用的地址是随机分布的,那么效果会降低。

页表的基本方法与Trie - 递归细分相同。 页表具有一些固定数量的级别,每个节点是固定大小的数组。 如果给定子节点的条目为null,则该节点覆盖的所有叶子都为空。 页表的主要优点是查找速度快,只需要几个位移和解引用。

让我们看一个2级页面表的简单Python实现:

class Pagetable(object):
  def __init__(self, num_bits=8):
    """Creates a new Pagetable with num_bits bits per level.

    Args:
      num_bits: The number of bits per pagetable level.
        A 2 level pagetable will be able to store indexes between 0 and 2^(num_bits*2).
    """
    self.num_bits = num_bits
    self.mask = (1 << num_bits) - 1
    self.root = [None] * (2 ** num_bits)

  def __getitem__(self, idx):
    page = self.root[idx >> self.num_bits]
    return page and page[idx & self.mask]

  def __setitem__(self, idx, val):
    page = self.root[idx >> self.num_bits]
    if not page:
      page = self.root[idx >> self.num_bits] = [None] * (2 ** self.num_bits)
    page[idx & self.mask] = val

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM