首页 > 解决方案 > 为什么 arr.flat.base 与 a.ravel().base 不同?

问题描述

我试图深入了解 Numpy 在内部的工作方式,但我对一些关于base数组展平的事情感到困惑。

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

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

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

这会打印 me 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)

我试图用谷歌搜索它,但我真的不明白为什么会发生这种情况。为什么base两者之间的行为会有所不同?

标签: pythonnumpynumpy-ndarray

解决方案


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)

都一样,b都是c意见。但:

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

正如预期的那样, thebcbase 都是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不是一个数组,所以不“服从”相同的base逻辑。

不管base, 修改biter修饰ba(and 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不同。


推荐阅读