Numpy 为什么Z[(0,2)]是视图,而Z[(0,2),(0)]是副本? 问题

Numpy 为什么Z[(0,2)]是视图,而Z[(0,2),(0)]是副本? 问题,numpy,matrix-indexing,Numpy,Matrix Indexing,为什么numpy元组索引行为不一致?请解释这些行为背后的理性或设计决策。在我的理解中,Z[0,2]和Z[0,2,0]都是元组索引,并且期望复制/查看的行为一致。如果这是错误的,请解释 import numpy as np Z = np.arange(36).reshape(3, 3, 4) print("Z is \n{}\n".format(Z)) b = Z[ (0,2) # Select Z[0][2] ] print("Tuple in

为什么numpy元组索引行为不一致?请解释这些行为背后的理性或设计决策。在我的理解中,Z[0,2]和Z[0,2,0]都是元组索引,并且期望复制/查看的行为一致。如果这是错误的,请解释

import numpy as np
Z = np.arange(36).reshape(3, 3, 4)
print("Z is \n{}\n".format(Z))

b =  Z[
    (0,2)      # Select Z[0][2]
]
print("Tuple indexing Z[(0,2)] is \n{}\nIs view? {}\n".format(
    b,
    b.base is not None
))

c = Z[         # Select Z[0][0][1] & Z[0][2][1]
    (0,2),
    (0)
]
print("Tuple indexing Z[(0, 2), (0)] is \n{}\nIs view? {}\n".format(
    c,
    c.base is not None
))

Numpy索引令人困惑,并且想知道人们是如何建立这种理解的。如果有一个很好的理解或备忘单的方法,请给出建议。

是逗号创建了元组。他们只是在需要的地方设置边界

因此

如果相同,请在前两个维度上选择。它是返回一个元素还是一个数组取决于Z有多少个维度

同样的解释适用于另一种情况

Z[(0, 2), (0)]
Z[( np.array([0,2]), 0)]
Z[ np.array([0,2]), 0]
相同-第一个维度使用列表/数组进行索引,因此是高级索引。这是副本

[ 8  9 10 11]
是三维阵列的一行;它是一个连续的Z块

距离Z是2行。它们不是连续的,所以在数据缓冲区中无法仅通过形状、步幅和偏移来识别它们

细节 __array_interface_uuu提供有关数组的底层数据的详细信息

In [146]: Z = np.arange(36).reshape(3,3,4)
In [147]: Z.__array_interface__
Out[147]: 
{'data': (38255712, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (3, 3, 4),
 'version': 3}
In [148]: Z.strides
Out[148]: (96, 32, 8)
Z2与两个选项相同:

In [158]: Z[0,0]
Out[158]: array([0, 1, 2, 3])
In [159]: Z[2,0]
Out[159]: array([24, 25, 26, 27])
事实并非如此

Z[0][0][1] & Z[0][2][1]
Z[0,0,1] & Z[0,2,1]
将其与2行切片进行比较:

In [156]: Z3 = Z[0:2,0]
In [157]: Z3.__array_interface__
Out[157]: 
{'data': (38255712, False),   # same as Z's
 'strides': (96, 8),
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (2, 4),
 'version': 3}

如果可以用形状、步幅和原始数据缓冲区的全部或部分描述新阵列,则返回视图。

非常感谢您的回答。然而,我担心我仍然无法得到返回视图的角度,如果新数组可以用形状、跨距和原始数据缓冲区的全部或部分来描述的话。如果你能看一看的话,可以打开。
In [149]: Z1 = Z[0,2]
In [150]: Z1
Out[150]: array([ 8,  9, 10, 11])
In [151]: Z1.__array_interface__
Out[151]: 
{'data': (38255776, False),    # 38255712+8*8
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (4,),
 'version': 3}
In [152]: Z2 = Z[[0,2],0]
In [153]: Z2
Out[153]: 
array([[ 0,  1,  2,  3],
       [24, 25, 26, 27]])
In [154]: Z2.__array_interface__
Out[154]: 
{'data': (31443104, False),     # an entirely different location
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (2, 4),
 'version': 3}
In [158]: Z[0,0]
Out[158]: array([0, 1, 2, 3])
In [159]: Z[2,0]
Out[159]: array([24, 25, 26, 27])
Z[0][0][1] & Z[0][2][1]
Z[0,0,1] & Z[0,2,1]
In [156]: Z3 = Z[0:2,0]
In [157]: Z3.__array_interface__
Out[157]: 
{'data': (38255712, False),   # same as Z's
 'strides': (96, 8),
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (2, 4),
 'version': 3}