代码之家  ›  专栏  ›  技术社区  ›  Daniel F

你怎么办。标志['OWNDATA]`,`ndarray。基'、'id(ndarray)'和'ndarray__array\u interface_u['data]`不同?

  •  1
  • Daniel F  · 技术社区  · 7 年前

    我好像有XY问题 this 关于如何判断阵列是否共享相同内存的问题。我检查的方式是错误的,我不知道为什么。

    让我们举几个例子

    test = np.ones((3,3))
    test2 = np.array(test, ndmin = 2, copy = False)
    test3 = np.array(test, ndmin = 3, copy = False)
    

    首先,让我们检查他们是否正在使用 .base

    test2.base is test
    False
    
    test3.base is test
    True
    

    看起来是这样的 test3 正在与共享数据 test 但是 test2 不是。事实上 test2.base is None => True ,我认为这意味着它是独立的内存(即副本)。

    当我与 .flags

    test2.flags['OWNDATA']
    True
    
    test3.flags['OWNDATA']
    False
    

    看起来又像是 测试3 正在共享数据,并且 测试2 是一个副本。

    但如果我和 python 内置 id(...)

    id(test)
    248896912
    
    id(test2)
    248896912
    
    id(test3)
    248897352
    

    现在 id (据说是内存中对象的地址)的 测验 测试2 匹配但 测试3 没有,这给人的印象与上述方法完全相反。

    当然,这两种印象都是错误的,因为:

    test.__array_interface__['data']
    (209580688, False)
    
    test2.__array_interface__['data']
    (209580688, False)
    
    test3.__array_interface__['data']
    (209580688, False)
    

    实际 buffer addresses 全部匹配。的确:

    test[0,0] = 2
    
    test, test2, test3
    
    (array([[ 2.,  1.,  1.],
            [ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]),  
    array([[ 2.,  1.,  1.],
            [ 1.,  1.,  1.],
            [ 1.,  1.,  1.]]), 
    array([[[ 2.,  1.,  1.],
             [ 1.,  1.,  1.],
             [ 1.,  1.,  1.]]]))
    

    所以如果 ndarray.base , ndarray.flags['OWNDATA'] id(ndarray) 不要告诉我内存是否共享,什么 他们告诉我?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Community CDub    4 年前

    你的大部分困惑来自这样一个事实: test2 test test3 测验 .

    ndarray.base

    如果将阵列创建为另一个对象的视图,则其 base 将指向另一个对象。。。或者NumPy将跟随该对象的 基础 链并使用“根基”。有时是一种选择,有时是另一种选择。有许多错误和向后兼容性问题。

    测试2 不是的视图 测验 . 测试2 测验 . 它的 基础 None 因为这不是一个视图。

    是的视图 测验 ,及其 基础 设置为 测验 .

    ndarray.flags['OWNDATA']

    如果阵列是视图,则设置此标志。如前所述, 测试3 是一个视图和 测试2 不是,因为 测试2 测验 .

    id

    身份证件 为对象提供一个数字标识符,保证与生存期与第一个重叠的任何对象的标识符不相同。此函数不关心NumPy和视图;无论任何视图关系如何,具有重叠生存期的两个不同数组将具有不同的ID。

    测试2 测验 ,因此它当然具有与自身相同的ID。 测试3 是具有重叠生存期的不同对象,因此它具有不同的ID。

    ndarray.__array_interface__['data']

    这是一个元组,其第一个元素是一个整数,表示数组第一个元素的内存地址。(第二个要素对问题不重要。) 测验 , 测试2 测试3 它们都使用相同的数据缓冲区,第一个元素的偏移量相同,因此它们在这里给出相同的值。但是,共享内存的两个数组并不总是具有相同的值,因为它们可能不具有相同的第一个元素:

    >>> import numpy
    >>> x = numpy.arange(5)
    >>> y = x[1:]
    >>> z = x[:-1]
    >>> x.__array_interface__['data']
    (39692208L, False)
    >>> y.__array_interface__['data']
    (39692212L, False)
    >>> z.__array_interface__['data']
    (39692208L, False)