简体   繁体   English

numpy:为什么(2,1)数组和垂直矩阵切片的差不是(2,1)数组

[英]Numpy: Why is difference of a (2,1) array and a vertical matrix slice not a (2,1) array

Consider the following code: 考虑以下代码:

>>x=np.array([1,3]).reshape(2,1)
array([[1],
   [3]])   
>>M=np.array([[1,2],[3,4]])
array([[1, 2],
   [3, 4]])
>>y=M[:,0]
>>x-y
array([[ 0,  2],
   [-2,  0]])

I would intuitively feel this should give a (2,1) vector of zeros. 我会直观地感觉到这应该给出零的(2,1)向量。

I am not saying, however, that this is how it should be done and everything else is stupid. 但是,我并不是说这是应该做的事情,其他所有事情都是愚蠢的。 I would simply love if someone could offer some logic that I can remember so things like this don't keep producing bugs in my code. 如果有人可以提供一些我能记住的逻辑,那么这样的事情就不会在我的代码中不断产生错误,我只是想知道。

Note that I am not asking how I can achieve what I want (I could reshape y), but I am hoping to get some deeper understanding of why Python/Numpy works as it does. 请注意,我并不是在问我如何实现自己想要的(我可以重塑y),而是希望对Python / Numpy为何能如此工作有更深入的了解。 Maybe I am doing something conceptually wrong? 也许我在概念上做错了吗?

Look at the shape of y . y的形状。 It is (2,) ; 它是(2,) ; 1d. 1D。 The source array is (2,2), but you are selecting one column. 源数组为(2,2),但是您正在选择一列。 M[:,0] not only selects the column, but removes that singleton dimension. M[:,0]不仅选择列,而且删除该单例尺寸。

So we have for the 2 operations, this change in shape: 因此,对于2个操作,我们需要进行形状更改:

M[:,0]: (2,2) => (2,)
x - y: (2,1) (2,) => (2,1), (1,2) => (2,2)

There are various ways of ensuring that y has the shape (2,1). 有多种方法可以确保y的形状为(2,1)。 Index with a list/vector, M[:,[0]] ; 带有列表/向量的索引, M[:,[0]] ; index with a slice, M[:,:1] . 带有切片的索引M[:,:1] Add a dimension, M[:,0,None] . 添加尺寸M[:,0,None]

Think also what happens when M[0,:] or M[0,0] . 还请考虑当M[0,:]M[0,0]时会发生什么。

numpy.array indexes such that a single value in any position collapses that dimension, while slicing retains it, even if the slice is only one element wide. numpy.array索引使得在任何位置的单个值都可以折叠该维度,而切片将保留该维度,即使切片只有一个元素宽。 This is completely consistent, for any number of dimensions: 对于任何数量的尺寸,这都是完全一致的:

>> A = numpy.arange(27).reshape(3, 3, 3)
>> A[0, 0, 0].shape
()

>> A[:, 0, 0].shape
(3,)

>> A[:, :, 0].shape
(3, 3)

>> A[:1, :1, :1].shape
(1, 1, 1)

Notice that every time a single number is used, that dimension is dropped. 请注意,每次使用单个数字时,该维将被删除。

You can obtain the semantics you expect by using numpy.matrix , where two single indexes return a order 0 array and all other types of indexing return matrices 您可以使用numpy.matrix获得所需的语义,其中两个单个索引返回一个0数组,所有其他类型的索引返回矩阵

>> M = numpy.asmatrix(numpy.arange(9).reshape(3, 3))

>> M[0, 0].shape
()

>> M[:, 0].shape   # This is different from the array
(3, 1)

>> M[:1, :1].shape
(1, 1)

Your example works as you expect when you use numpy.matrix : 您的示例使用numpy.matrix时可以按预期numpy.matrix

>> x = numpy.matrix([[1],[3]])
>> M = numpy.matrix([[1,2],[3,4]])
>> y = M[:, 0]
>> x - y
matrix([[0],
        [0]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM