请考虑以下内容:
import numpy as np
X = np.ones((5,5))
print(X[:,0].shape)
print(X[:,0:1].shape)
X[:,0].shape
返回(5,)
X[:,0:1].shape
返回(5,1)
。
在两种情况下都选择了同一列(已建立索引),但是为什么会发生这种情况?背后的逻辑是什么?
X[:,-1:].shape
和X[:,-1].shape
答案 0 :(得分:1)
此行为可以通过以下事实来解释:与切片索引不同,使用说i
的整数索引将返回与切片i:i+1
相同的值,但返回的维数对象减少1
。 docs中对此进行了解释:
特别是,第p个元素为整数(以及所有其他条目:)的选择元组将返回尺寸为N-1的相应子数组
我们可以编写一个简单的子类来仔细研究np.ndarray
如何处理索引,并查看在每次调用中__getitem__
dunder会收到什么:
class ndarray_getitem_print(np.ndarray):
def __getitem__(self, t):
print(t)
return super().__getitem__(t)
现在让我们实例化ndarray_getitem_print
,看看用片和整数建立索引有什么区别:
a = ndarray_getitem_print((5,5))
a[:,0:1]
(slice(None, None, None), slice(0, 1, None))
(-5, -1)
(-4, -1)
(-3, -1)
(-2, -1)
(-1, -1)
ndarray_getitem_print([[1.],
[1.],
[1.],
[1.],
[1.]])
而使用0
沿第二轴索引,将产生一个输出ndarray,其中每个项目都具有一维形状,即(-k,)
a[:,0]
(slice(None, None, None), 0)
(-5,)
(-4,)
(-3,)
(-2,)
(-1,)
ndarray_getitem_print([1., 1., 1., 1., 1.])
答案 1 :(得分:0)
我认为是因为索引?如果您打印两个函数的结果,则它们是不同的。在NxM np.array中,其数组为arrays。当用X [:,0]索引时,数组中的数组结构丢失。因此,shape只看到您得到的是单个数组而不是多维数组的内容。不带范围的AFAIK索引从列表/集合/内容中获取值。而按范围寻址时会切片。
访问类型时您会看到
>>> b = X[:,0]
>>> c = X[:,0:1]
>>> type(b)
<class 'numpy.ndarray'>
>>> type(c)
<class 'numpy.ndarray'>
>>> type(c[0])
<class 'numpy.ndarray'>
>>> type(b[0])
<class 'numpy.float64'>
仅显示两者之间的差异。
>>> c[0]
array([1.])
>>> b[0]
1.0