In [15]: a = np.arange(18)
...: b = a.reshape(3,6)
我喜欢检查数组的属性:
In [16]: a.__array_interface__
Out[16]:
{'data': (65611776, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (18,),
'version': 3}
In [17]: b.__array_interface__
Out[17]:
{'data': (65611776, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (3, 6),
'version': 3}
请注意,data 对两者都是相同的。 b 是 view 的 a。它是一个新的数组对象,但它共享底层数据缓冲区。它的形状不同,但对a 的更改将显示为b 的更改(反之亦然)。
查看有关 view 与 copy 的文档。这是numpy中的一个重要区别,需要好好理解。
有时reshape 必须返回一个副本,就像order 被更改时一样。意识到reshape 不能改变元素的数量也很重要。
还有一个reshape 函数,在大多数情况下与方法相同。
shape 属性也可以直接更改:
In [19]: a.shape = (6,3)
In [20]: a
Out[20]:
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]])
In [21]: b
Out[21]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
该操作是就地的,修改a 本身。它比reshape 更严格一些,并且不经常使用。例如,我们可以用一行创建b:
b = np.arange(18).reshape(3,6)
resize 的主要区别在于它可以更改元素的数量。它可以截断,也可以增加大小。 resize 方法和函数都这样做,但有不同的“填充”规则。而resize 方法就地运行。
在您的示例中,a.resize(3,6) 就地更改了a,更改了其shape,但没有更改其数据缓冲区或b 到该缓冲区的链接。因此a 的更改也显示为b 的更改。
我的a 在原地shape 更改后仍然有相同的data:
In [22]: a.__array_interface__
Out[22]:
{'data': (65611776, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (6, 3),
'version': 3}
在 resize 方法之后使用相同的 data。
In [23]: a.resize(3,6)
In [24]: a.__array_interface__
Out[24]:
{'data': (65611776, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (3, 6),
'version': 3}
请注意,如果我尝试以更改元素总数的方式 resize a,我会收到错误消息。那是因为b共享数据缓冲区,我们不能改变a的大小而不影响b的大小。
In [28]: a.resize(4,6)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-28-f7d47a627631> in <module>
----> 1 a.resize(4,6)
ValueError: cannot resize an array that references or is referenced
by another array in this way.
Use the np.resize function or refcheck=False
我想你会发现np.reshape 和a.reshape 被使用了很多。 resize 在这两种形式中的使用频率几乎没有。 reshape 更可预测且更安全。 resize 可以做同样的事情,但它也会让你做危险的事情。
我将重点了解view 和copy 之间的区别,其次是创建新数组和进行就地更改之间的区别。