2

I want to get the slice of x[start1:stop1:step1 ] and x[start2:stop2:step2] in a single array.

Is there any syntax in Python like this:

x[start1:stop1:step1  +  start2:stop2:step2]

In Matlab it is simply:

x(start1:step1:stop1  start2:step2:stop2)


update:

I see many answers suggest concatenation.

My intial goal is to do slice for higher dimension array, for example in 2D:

x[start1:stop1 +  start2:stop2,  start3:stop3  +  start4:stop4]

Concatenation is okay. But it seems too complicated in high dimension.

Is there a way as simple as Matlab?

x(start1:stop1  start2:stop2, start3:stop3  start4:stop4 )

can we concatenate the array index, instead of the array itself?

see my solution below

the Tartan

2
  • 1
    Do you have numpy? Are you going to use it? Commented Jun 5, 2018 at 4:54
  • It would be simpler to understand with a concrete example. Commented Jun 5, 2018 at 5:17

6 Answers 6

2

You can concatenate two arrays (lists) like this: x[start1:stop1:step1] + x[start2:stop2:step2]

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

1 Comment

This will work for lists but it won't concatenate arrays, it will add them together
2

Your answer indicates you are using numpy, so you can use r_ for this instead of constructing ranges.

test=np.random.random((20,20))
test[np.r_[1:8:2, 1:9:3], :][:, np.r_[1:9:3, 2:10:3]]

Indexing multidimensional arrays using sequences has been designed to work a bit differently from indexing using slices. e.g. test[[0, 1, 2], [3, 4, 5]] will return an array containing test[0, 3], test[1, 4], test[2, 5]. That's why test[D1, D2] in your answer doesn't work.

If you want a slightly more convenient syntax you could make a class extending ndarray with an altered method for handling indices:

class MultiArray(np.ndarray):
    """ An array that can be indexed by multiple lists or arrays of indices
    in the same way as by slices e.g.
    m = MultiArray([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
    m[[1, 2], [0, 3, 2]]  # returns [[5, 8, 7], [9, 12, 11]]

    Returns a standard array.
    """
    def __new__(cls, input_array):
        return np.asarray(input_array).view(cls)

    def __getitem__(self, key):
        r = np.array(self)
        if type(key) is tuple:
            for dimension, index in enumerate(key):
                indices = [slice(None)] * len(key)
                indices[dimension] = index
                r = r[tuple(indices)]
            return r
        else:
            return r[key]     

print(MultiArray(test)[np.r_[1:8:2, 1:9:3], np.r_[1:9:3, 2:10:3]])

Comments

1

This operation is also pretty easy in python. Once you've defined the list you can do your like this:

new_list = lst[start1:stop1:step1] + lst[start2:stop2:step2]

hope this helps.

Comments

0

Concatenating the two lists, as in Jonas's answer, is the simplest solution, and usually the best.

If you're worried about making temporary lists, you can do something slightly more complicated, like:

[elem for i, elem in enumerate(x) 
 if i in range(start1, stop1, step1) or i in range(start2, stop2, step2)]

… or:

list(itertools.chain(itertools.islice(x, start1, stop1, step1),
                     itertools.islice(x, start2, stop2, step2)))

However, I'd expect either one to be a whole lot slower unless the two sublists are so huge that memory allocation time dominates everything, and of course they're a lot more complicated and less readable.

The only real advantage of either of these solutions is if you don't actually need the list, you can turn them into lazy iterators easily:

(elem for i, elem in enumerate(x) 
 if i in range(start1, stop1, step1) or i in range(start2, stop2, step2))

itertools.chain(itertools.islice(x, start1, stop1, step1),
                itertools.islice(x, start2, stop2, step2))

(In fact, the second one is just the lazy equivalent of Jonas's answer: islice(x, start1, stop1, step1) does the same thing as x[start1:stop1:step1], and chain(a, b) does the same thing as a + b.)

Comments

0

Here is my solution:

D1=list(range(start1,stop1,step1))+list(range(start2,stop2,step2))
D2=list(range(start3,stop3,step3))+list(range(start4,stop4,step4))+"add more if you want"
x[D1,:][:,D2]

the effect is to select out the black regions in this Tartan pattern, from the whole cloth.

arbitary cut

for example, test is a 2D array.

D1 and D2 are some list of index in column and row. We wannt some cut

import numpy as np
test=np.random.random((20,20))
D1=list(range(1,8,2))+list(range(1,9,3))
D2=list(range(1,9,3))+list(range(2,10,3))
print(test[D1,:].shape)
print(test[:,D2].shape)
# test[D1,D2] will create error
output=test[D1,:][:,D2]
type(output)
output.shape

However, it is still unclear, why doesn't test[D1,D2] work.

Comments

-2

Concatenate is a great way, or alternatively, you can join the two lists

part1 = x[start1:stop1:step1]
part2 = x[start2:stop2:step2]
mergedlist = part1 + part2

mergedlist = list(set(part1 + part2))

This will create a merged list, with a shallow copy of the items in the first list, followed by a shallow copy of the items in the second list.

If you want deep copy, you may use copy.deepcopy commands.

4 Comments

Can you explain how this is different from the other two answers aside from just splitting it into multiple lines?
Great question, I can not realize other people have posted the answer, so great, I can provide a new way using set, which gives actually the same..... Time is the issue, this can not blame me though.
Your answer says "Concatenate is a great way, or alternatively, you can join the two lists", so obviously you think you've written an alternative to ccncatenation, but you haven't, you've written the sam thing. And your second answer just concatenates, then converts the result to a set and back to a list, which has no effect except to take longer, lose duplicates, scramble the order, and raise an exception if the elements aren't hashable.
"I can provide a new way using set, which gives actually the same" nope.

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.