【问题标题】:How can I share memory between numpy arrays?如何在 numpy 数组之间共享内存?
【发布时间】:2019-08-17 16:45:24
【问题描述】:

我有一个大小为 100x100 的大型 numpy 数组。在这 10000 个值中,只有大约 50 个唯一值。所以我想创建第二个长度为 50 的数组,包含这些唯一值,然后以某种方式将大数组映射到较小的数组。实际上,我只想在我的系统中存储 50 个值,而不是冗余的 10000 个值。

数组切片似乎共享内存,但一旦我使用特定索引,内存共享就会丢失。

a = np.array([1,2,3,4,5])
b = a[:3]
indices = [0,1,2]
c = a[indices]
print(b,c)
print(np.shares_memory(a,b),np.shares_memory(a,c))

这给出了输出:

[1 2 3] [1 2 3]
True False

即使 b 和 c 引用相同的 a 值,b(切片)与 a 共享内存,而 c 不。如果我执行 b[0] = 100,a[0] 也变为 100,因为它们共享内存。 c 的情况并非如此。

我想让c,它是所有来自a的值的集合,与a共享内存。

【问题讨论】:

  • 我不完全理解你的输出应该是什么样子,但是 numpy.unique() 对你有帮助吗?
  • 您需要阅读更多关于如何定义和存储数组的基础知识,以及viewcopy 之间的区别。 view 可以共享内存,因为它只是在shapestrides(和内存指针)方面有所不同。但是在indices 的情况下共享内存需要将indices 列表与c 一起存储;实际上,每次访问 c 时都会重新执行索引操作。
  • 数组的 dtype 是什么,即您要存储的元素的类型是什么?
  • @JohnZwinck dtype 是 numpy.int64。
  • @hpaulj 所以在索引的情况下是不可能的?

标签: python numpy memory


【解决方案1】:

一般来说,以这种方式无法节省内存。原因是您的数据由 64 位整数组成,而指针也是 64 位整数,因此如果您尝试在某个辅助数组中仅将每个值存储一次然后指向这些值,您最终将基本上使用相同的空间。

如果您的某些数组是其他数组的子集,或者您存储的是长字符串等大型类型,则答案会有所不同。

【讨论】:

    【解决方案2】:

    所以用一小组唯一值创建一个随机数组:

    In [45]: x = np.random.randint(0,10,(10,10))                                                                 
    In [46]: x                                                                                                   
    Out[46]: 
    array([[4, 3, 8, 5, 4, 8, 8, 1, 8, 1],
           [9, 2, 7, 2, 9, 5, 3, 9, 3, 3],
           [6, 2, 6, 9, 4, 2, 3, 4, 6, 7],
           [1, 0, 2, 1, 0, 9, 4, 2, 6, 2],
           [8, 1, 6, 8, 3, 9, 5, 0, 8, 5],
           [4, 9, 1, 4, 1, 2, 8, 4, 7, 2],
           [4, 5, 2, 4, 8, 0, 1, 4, 4, 7],
           [2, 2, 0, 5, 3, 0, 3, 3, 3, 9],
           [3, 1, 0, 6, 4, 8, 8, 3, 5, 2],
           [7, 5, 9, 2, 8, 0, 8, 1, 7, 8]])
    

    找出独一无二的:

    In [48]: np.unique(x)                                                                                        
    Out[48]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    

    更好的是唯一值加上一个数组,可以让我们将这些值映射到原始值:

    In [49]: np.unique(x, return_inverse=True)                                                                   
    Out[49]: 
    (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
     array([4, 3, 8, 5, 4, 8, 8, 1, 8, 1, 9, 2, 7, 2, 9, 5, 3, 9, 3, 3, 6, 2,
            6, 9, 4, 2, 3, 4, 6, 7, 1, 0, 2, 1, 0, 9, 4, 2, 6, 2, 8, 1, 6, 8,
            3, 9, 5, 0, 8, 5, 4, 9, 1, 4, 1, 2, 8, 4, 7, 2, 4, 5, 2, 4, 8, 0,
            1, 4, 4, 7, 2, 2, 0, 5, 3, 0, 3, 3, 3, 9, 3, 1, 0, 6, 4, 8, 8, 3,
            5, 2, 7, 5, 9, 2, 8, 0, 8, 1, 7, 8]))
    

    原始元素中的每个元素的反向映射都有一个值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 2020-12-23
      • 1970-01-01
      • 2013-07-04
      • 1970-01-01
      • 2020-02-27
      相关资源
      最近更新 更多