如何解决numpy - 为什么 Z[(0,2)] 可以在某些情况下查看而在其他情况下可以复制?
继续问题numpy - why Z[(0,2)] is view but Z[(0,2),(0)] is copy?。我得到了答案并了解到 逗号 触发高级索引会产生完全不同的索引。答案还提供了一种使用 __array_interface__
来理解复制/查看行为的方法。
但是显然我还没有深入到答案的这一部分。
如果新数组可以用形状、步幅和原始数据缓冲区的全部或部分来描述,则返回一个视图
因为我仍然无法解释为什么下面的行为不同。因此,提出一个新问题以深入了解此 (shape,stride)
机制,以了解查看/复制的工作原理。
请详细说明 numpy 如何使用 shhape
和 stride
来确定是否返回副本。
X = np.arange(36).reshape(3,3,4)
print("X is \n{}\n".format(X))
print("X.__array_interface__ \n{}\n".format(X.__array_interface__))
_x = X[
0,2
]
print("X[0,1] is \n{}\nIs view? {}\n".format(
_x,_x.base is not None
))
print("_x.__array_interface__ is \n{}\n".format(_x.__array_interface__))
---
X is
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]
[[24 25 26 27]
[28 29 30 31]
[32 33 34 35]]]
X.__array_interface__
{'data': (94194168544480,False),'strides': None,'descr': [('','<i8')],'typestr': '<i8','shape': (3,4),'version': 3}
X[0,1] is
[ 8 9 10 11]
Is view? True
_x.__array_interface__ is
{'data': (94194168544544,'shape': (4,),'version': 3}
Y = np.arange(12).reshape(3,4)
print("Y is \n{}\n".format(Y))
print("Y.__array_interface__ is \n{}\n".format(Y.__array_interface__))
_y = Y[
0,1
]
print("Y[0,1] is \n{}\nIs view {}\n".format(
_y,_y.base is not None
))
print(".Y[0,1].__array_interface__ is \n{}\n".format(_y.__array_interface__))
---
Y is
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
Y.__array_interface__ is
{'data': (94194175499568,'version': 3}
Y[0,1] is
1
Is view False
.Y[0,1].__array_interface__ is
{'data': (94194177613184,'shape': (),'version': 3,'__ref': array(1)}
解决方法
In [195]: Y = np.arange(12).reshape(3,4)
In [196]: Y
Out[196]:
array([[ 0,1,2,3],[ 4,5,6,7],[ 8,9,10,11]])
在二维数组上使用 2 个标量索引会从数组中返回一个元素,即 numpy
标量。
In [197]: Y[0,1]
Out[197]: 1
In [198]: type(_)
Out[198]: numpy.int64
在大多数情况下,我们可以将此类对象视为 Python 整数。它确实具有 ndarray
之类的属性,例如 shape
甚至 __array_interface__
,但它不是 ndarray
。
相比之下,数组的“切片”本身就是一个数组:
In [199]: Y[0,:]
Out[199]: array([0,3])
In [200]: type(_)
Out[200]: numpy.ndarray
https://numpy.org/doc/stable/reference/arrays.scalars.html
该文档有一小部分展示了如何将数组标量视为 0d 数组。
In [209]: Y.__array_interface__['data']
Out[209]: (38135024,False)
In [210]: Y[0,0].__array_interface__['data']
Out[210]: (35130688,False)
In [211]: Y[0,...].__array_interface__['data']
Out[211]: (38135024,False)
In [212]: Y[0,0] # array scalar
Out[212]: 0
In [213]: Y[0,...] # 0d array
Out[213]: array(0)
要获取数组的元素,作为“普通”Python 类型:
In [215]: Y.item(0,0)
Out[215]: 0
In [216]: type(_)
Out[216]: int
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。