【问题标题】:Python: How to efficiently implement large symmetric array with many empty entriesPython:如何有效地实现具有许多空条目的大型对称数组
【发布时间】:2014-12-02 00:21:17
【问题描述】:

我正在使用一个非常大的二维方形数组,其条目是整数列表。这不是一成不变的,而是说它是一个 w x w 数组,其中 w=15000,每个条目是一个整数列表,随机大小从 0 到 400。 这有两个特点:

  1. 是对称的
  2. 它的许多条目是空列表,包括对角线上的那些

现在,我只是利用第一部分并像下面的伪代码一样实现它:

F=[ [ [] for i in range(w)] for j in range(w) ] # Initiate a blank w X w array
for i in range(w):
    for j in range(i):
    If (condition):
        F[i][j] = [A list of integers]

最后,我将其余的值分配如下:

for i in range(w):
    for j in range(w):
        F[i][j]=F[i][j] # Reference, thus size of F does not increase much

我不是经验丰富的程序员,我觉得这种方法可能效率不高。特别是,我觉得我没有利用许多条目为空的事实。

我可以有一个更有效的列表 F 以便它不会为最终为空的条目占用任何空间吗?

请注意,正确分配“坐标”x、y 仍然很重要。

【问题讨论】:

  • numpy 中的稀疏数组可能吗?
  • 有许多不同的“稀疏数组”数据结构,它们有不同的权衡。您将不得不做一些研究,因为一般来说没有人能告诉您哪个是“最好的”。
  • 同时,如果你从原生 Python 列表切换到 NumPy 数组,你可以使用scipy.sparse 来处理大多数在 Python 中编写起来很笨重的数据结构。
  • 你知道它可能有多稀疏吗?如果 50% 的条目平均长度为 200 项,则实际数据很大(112.5 亿个值),而空的和对称的条目上“浪费”的空间与总数相比非常小。所以也许你还不如坚持你所拥有的。如果它的占用率为 0.01%,那么字典或自定义“稀疏矩阵”数据结构更有可能产生实际影响。如果它 99.75% 被占用,而只有 0.25% 的条目是空的,那就别再为它们节省空间了。
  • @geo909:这里要考虑的另一件事是,平均长度为 200 的 225M Python 列表没什么好打喷嚏的。使用 15K*15K*400 的 NumPy 数组可能会比通过将第三维固定为 400 而不是让它在 0-400 之间变化而浪费的时间和/或空间节省更多。另外,你的整数范围是多少? 11.25G int32 对象的大小是 11.25G 8 字节指针大小的一半,即使它们都是 0,如果它们均匀分布,您还可以节省多达 4G 24 字节 int 对象。

标签: python arrays list size memory-efficient


【解决方案1】:

存储稀疏矩阵有多种方式,Wikipedia is a good place to start。在不知道你打算用这些做什么的情况下,没有人可以告诉你该使用哪一个。

例如,Keys 设计的字典在 Python 中构建非常简单:

d = collections.defaultdict(list)
for i in range(w):
    for j in range(w):
        if condition:
            d[i, j] = [a list of integers]

就是这样。现在,稍后检索或更改值:

value = d[i, j]
d[i, j].append(3)

但是,如果您想按顺序迭代所有非空行,然后按顺序迭代每行的所有非空列,这将是非常低效的。天真的解决方案是遍历每个 i 和 j 并查找 d[i, j],但这将分配一个新的空列表来填充每个位置。您可以改为对键进行排序,但这也可能很慢。您可以在字典旁边保留按两种顺序排序的坐标列表 - 但此时,字典只是增加了额外的开销,而不是仅在每个坐标列表中粘贴对值的引用。

因此,还有其他更适合不同用途的替代品。

如果您愿意使用 NumPy/SciPy 数组,scipy.sparse 处理 2D 稀疏数组。当然,它们通常是数字数组,但是您可以将dtype=object 与大多数类型一起使用(尽管这确实意味着“空”插槽将具有None 而不是[],在这些情况下也有一些奇怪的限制)。 (还有一些文档(抱歉,没有链接……)解释了稀疏矩阵是如何实现的,以及如何在纯 Python/NumPy 中进行等效操作,您可以使用它来创建 WxWx400 稀疏整数数组。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2018-12-31
    • 2022-10-24
    • 2019-09-06
    • 2018-04-08
    • 2016-11-14
    相关资源
    最近更新 更多