2

I create an array in numpy as

a = np.ones([5 , 5])

I will then get an output as 5x5 array full of 1s. I would like to keep the outer elements as 1, and inner elements as 0. So I would like output to be:

[[ 1.  1.  1.  1.  1.]
 [ 1.  0.  0.  0.  1.]
 [ 1.  0.  0.  0.  1.]
 [ 1.  0.  0.  0.  1.]
 [ 1.  1.  1.  1.  1.]]

Is there any way with which we could do this in a single line? (I have read about inner() but I dont know how to get it working with this single array)

1 Answer 1

2

Yes, we can use slicing for this:

a[1:-1, 1:-1] = 0

Or for a generic multidimensional array:

a[(slice(1, -1),) * a.ndim] = 0

but usually it would be better to construct such matrix in another way. This produces:

>>> a = np.ones([5 , 5])
>>> a[1:-1, 1:-1] = 0
>>> a
array([[1., 1., 1., 1., 1.],
       [1., 0., 0., 0., 1.],
       [1., 0., 0., 0., 1.],
       [1., 0., 0., 0., 1.],
       [1., 1., 1., 1., 1.]])

and for instance for a 3d case (imagine some sort of cube):

>>> a = np.ones([5 , 5, 5])
>>> a[(slice(1, -1),) * a.ndim] = 0
>>> a
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., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 0., 0., 0., 1.],
        [1., 1., 1., 1., 1.]],

       [[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]]])
Sign up to request clarification or add additional context in comments.

5 Comments

Can also spell it a[np.s_[1:-1,] * a.ndim] = 0
@Eric: true, but behind the curtains, np.s_[1:-1,] simply returns a (slice(1,-1),) tuple, so it will only cost more computational resources, and furthermore more dependency on numpy whereas slice is a vanilla Python class.
Depending on numpy in the context of preparing a numpy array doesn't sound like a problem to me. It may actually be faster, because python can load the slice in a single opcode, rather then having to call the slice function
@Eric: yes, but here you call the __getitem__ from the s_ attribute.
@Eric: I tested it, with numpy (return s_[1:-1]) it takes 2.986656811001012s for 10M runs, for return (slice(1, -1),), it takes 1.8174990950210486s.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.