2

Say we have

a = np.ones((3,3,3))

and

slices = [(0, 1, slice(None)), (0, slice(None), 0),  (slice(None), 1, 0)]

Is there a simple way to select/change values of a from slices?

For example, I want to assign 0 to a under slices such that a becomes

array([[[0., 1., 1.],
        [0., 0., 0.],
        [0., 1., 1.]],

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

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

An iterative way is to do

for t in slices:
    a[t] = 0

Is there a better way to make use of the indices like np.r_ like what's used by JoshAdel in Assign value to multiple slices in numpy?

I am hoping to achieve something like a[SLICES] = 0 and change all part of a from each slice in slices to 0.

2
  • that is already very simple and appropriate, isn't it? Commented Feb 25, 2018 at 18:02
  • @Rockbar that is true. I am just wondering whether there are alternatives like np.r. Commented Feb 25, 2018 at 18:11

1 Answer 1

3

Do you know what r_ does? It converts the slices into ranges, and then concatenates the whole mess together.

I don't know if you can use r_ or something similar to construct the required indices. But:

In [168]: idx = np.where(a==0)
In [169]: idx
Out[169]: 
(array([0, 0, 0, 0, 0, 1, 2]),
 array([0, 1, 1, 1, 2, 1, 1]),
 array([0, 0, 1, 2, 0, 0, 0]))

this is gives us an idea of the required indexing arrays (minus some likely duplicates).


It might be possible to concatenate these 3 ogrid lists into a composite:

In [181]: np.ogrid[0:1,1:2,:3]
Out[181]: [array([[[0]]]), array([[[1]]]), array([[[0, 1, 2]]])]

In [182]: np.ogrid[0:1,:3,0:1]
Out[182]: 
[array([[[0]]]), array([[[0],
         [1],
         [2]]]), array([[[0]]])]

In [183]: np.ogrid[:3,1:2,0:1]
Out[183]: 
[array([[[0]],

        [[1]],

        [[2]]]), array([[[1]]]), array([[[0]]])]

Individually they select the 0s in a.

It may be easiest to convert them into their raveled equivalents, and join the resulting 1d arrays.

In [188]: np.ravel_multi_index(Out[181],(3,3,3))
Out[188]: array([[[3, 4, 5]]])
etc
In [195]: np.hstack([Out[188].ravel(), Out[189].ravel(), Out[190].ravel()])
Out[195]: array([ 3,  4,  5,  0,  3,  6,  3, 12, 21])
In [197]: a.flat[_]
Out[197]: array([0., 0., 0., 0., 0., 0., 0., 0., 0.])

In [199]: np.unravel_index(Out[195],(3,3,3))
Out[199]: 
(array([0, 0, 0, 0, 0, 0, 0, 1, 2]),
 array([1, 1, 1, 0, 1, 2, 1, 1, 1]),
 array([0, 1, 2, 0, 0, 0, 0, 0, 0]))

Out[169] and Out[199] have the same values, except for duplicates.

This is a generalization of the problem of joining several 1d slices. Indexing and then concatenating takes about as much time as concatenating the indices first.

Sign up to request clarification or add additional context in comments.

1 Comment

I think you may be right that there is no direct way to achieve things like np.r_. These analyses and trial with np.ogrid are solid.

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.