3
votes

Suppose we have a matrix s of size 639 by 668, this matrix is fully composed by values of -1. We want to access and replace a section of 28X28 (e.g., Top-left corner), leaving a border of -1 around that specific submatrix. For that task we have initialized the following vector p (in MATLAB) and then access the section:

>> 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:

>>> 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). ¿It is possible to access that section in numpy using a similar process as in MATLAB?

Thanks in advance.

2

2 Answers

1
votes

You can do what you want with a slice object:

>>> 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.]])
1
votes

You want to use slice notation, as in a[1:29,1:29], not a list.

If you want, you can create a slice object using p = slice(1,29) to get more matlab behavior.

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.]])