简体   繁体   English

使用向量作为索引切片numpy矩阵

[英]Slice numpy matrix using vectors as indices

Suppose we have a matrix s of size 639 by 668, this matrix is fully composed by values of -1. 假设我们有由668尺寸639的矩阵S,这个矩阵完全由-1值组成。 We want to access and replace a section of 28X28 (eg, Top-left corner), leaving a border of -1 around that specific submatrix. 我们想要访问和替换28X28的一部分(例如,左上角),在该特定子矩阵周围留下-1的边界。 For that task we have initialized the following vector p (in MATLAB) and then access the section: 对于该任务,我们初始化了以下向量p (在MATLAB中),然后访问该部分:

>> s = -ones(639, 668);
>> p = 2:29;
>> section = s(p, p); %Size 28X28
>> size(section)

   ans =

   28    28

Now we want to rewrite that code in Numpy/Python, assuming that the slicing is equivalent: 现在我们想要在Numpy / Python中重写该代码,假设切片是等效的:

>>> import numpy as np
>>> s = -np.ones((639, 668))
>>> p = np.arange(1, 29)
>>> section = s[p, p]
>>> section.shape
(1, 28)

In this case is not possible to access the same section using the same vector (Note that the indices in numpy are based on 0). 在这种情况下,不可能使用相同的向量访问相同的部分(注意numpy中的索引基于0)。 ¿It is possible to access that section in numpy using a similar process as in MATLAB? ¿可以使用与MATLAB中类似的过程在numpy中访问该部分吗?

Thanks in advance. 提前致谢。

You want to use slice notation , as in a[1:29,1:29] , not a list. 您想要使用切片表示法 ,如a[1:29,1:29] ,而不是列表。

If you want, you can create a slice object using p = slice(1,29) to get more matlab behavior. 如果需要,可以使用p = slice(1,29)创建slice对象以获得更多matlab行为。

In [9]: a = -np.ones((10,10))

In [10]: a
Out[10]: 
array([[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.]])

In [11]: a[1:4,1:4] = 9

In [12]: a
Out[12]: 
array([[-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1.,  9.,  9.,  9., -1., -1., -1., -1., -1., -1.],
       [-1.,  9.,  9.,  9., -1., -1., -1., -1., -1., -1.],
       [-1.,  9.,  9.,  9., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.],
       [-1., -1., -1., -1., -1., -1., -1., -1., -1., -1.]])


In [13]: p = slice(1,4)

In [14]: a[p,p]
Out[14]: 
array([[ 9.,  9.,  9.],
       [ 9.,  9.,  9.],
       [ 9.,  9.,  9.]])

You can do what you want with a slice object: 您可以使用slice对象执行所需操作:

>>> p = slice(1, 29)
>>> section = s[p, p]
>>> section.shape
(28L, 28L)

You could get a similar, yet different result, broadcasting your indexing array: 您可以获得类似但不同的结果,广播您的索引数组:

>>> p = np.arange(1, 19)
>>> section_bis = s[p[:, None], p]
>>> section_bis.shape
(28L, 28L)

The problem is that what you now have is a copy, not a view of your original array, because you have used fancy indexing: 问题是你现在拥有的是一个副本,而不是原始数组的视图,因为你使用了花哨的索引:

>>> section_bis[:] = 0
>>> s
array([[-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.],
       ..., 
       [-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.]])

But: 但:

>>> section[:] = 0
>>>
array([[-1., -1., -1., ..., -1., -1., -1.],
       [-1.,  0.,  0., ..., -1., -1., -1.],
       [-1.,  0.,  0., ..., -1., -1., -1.],
       ..., 
       [-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.],
       [-1., -1., -1., ..., -1., -1., -1.]])

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

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