为什么 arr.flat.base 与 a.ravel().base 不同?

Why arr.flat.base is different from the a.ravel().base?

我正在尝试深入了解 Numpy 的内部工作原理,但我对 base 和数组展平的一些内容感到困惑。

import numpy as np
a = np.arange(12, dtype=int).reshape((3, 4))

所以,我们有了这个简单的数组。然后我尝试使用 flatravel():

flat_iter = a.flat
print(flat_iter.base is a)

这打印出我 True,这正是我所期待的。

a_ravel = a.ravel()
print(a_ravel.base is a)

然而,这给了我 False。为什么?

flat_iter.base 似乎对应于重塑的 a 数组,即 np.arange(12, dtype=int).reshape((3, 4))。然而,a_ravel.base似乎对应于np.arange(12, dtype=int)

我已经尝试 google 关于它,但我真的不明白为什么会这样。为什么 base 行为在两者之间会有所不同?

In [82]: a = np.arange(5)
In [83]: b = a.reshape(5,1)
In [84]: c = b.ravel()
In [85]: biter=b.flat

现在检查数据缓冲区位置:

In [86]: a.__array_interface__['data']
Out[86]: (44761168, False)
In [87]: b.__array_interface__['data']
Out[87]: (44761168, False)
In [88]: c.__array_interface__['data']
Out[88]: (44761168, False)

都一样,bc都是浏览量。但是:

In [89]: biter.__array_interface__['data']
Traceback (most recent call last):
  File "<ipython-input-89-9d5e2ed1a08d>", line 1, in <module>
    biter.__array_interface__['data']
AttributeError: 'numpy.flatiter' object has no attribute '__array_interface__'

flatiter不是数组!

In [90]: a.base              # None
In [91]: b.base
Out[91]: array([0, 1, 2, 3, 4])
In [92]: b.base is a
Out[92]: True
In [93]: c.base is a
Out[93]: True

正如预期的那样,bc 基数都是 a

但是 b.flat 基数是 b:

In [94]: biter.base
Out[94]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])
In [95]: biter.base is b
Out[95]: True
In [96]: biter.base is a      # not a
Out[96]: False

同样 biter 不是数组,因此 'obey' 与 base 逻辑不同。

不考虑 base,修改 biter 会修改 ba(以及 c):

In [97]: biter[::2] = 10
In [98]: b
Out[98]: 
array([[10],
       [ 1],
       [10],
       [ 3],
       [10]])
In [99]: a
Out[99]: array([10,  1, 10,  3, 10])

所以简短的回答是 flatiter 基础与 view's 基础不同。