在python中添加多个切片

时间:2018-06-05 04:50:14

标签: python slice

我希望在单个数组中得到x[start1:stop1:step1 ]x[start2:stop2:step2]的切片。

Python中是否有这样的语法:

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

在Matlab中,它只是:

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


更新

我看到许多答案表明连接。

我的目标是为更高维度数组进行切片,例如在2D中:

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

连接没问题。但在高维度上似乎太复杂了。

有没有像Matlab一样简单的方法?

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

我们可以连接数组索引而不是数组本身吗?

see my solution below

the Tartan

6 个答案:

答案 0 :(得分:2)

您可以连接两个数组(列表),如下所示:x[start1:stop1:step1] + x[start2:stop2:step2]

答案 1 :(得分:1)

这个操作在python中也很简单。一旦您定义了列表,就可以这样做:

if let error = error {
    print(error.localizedDescription)
    return
 }
 if let httpResponse = response as HTTPURLResponse {
    if httpResponse.statusCode == 200 {
         // do your json deserialization after you verify you 
         // got a 200 / OK from the server
         do {
            if let data = data {
                let jsonData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
                self.createCoinPairData(with: jsonData)
            } else {
                self.delegate?.updateInfoLabelContent(content: .noInternetConnection)
            }
        } catch {
            self.delegate?.updateInfoLabelContent(content: .error)
            print("catch error", error, data?.description as Any)
            self.retrieveCoinPairData()
        }
    } else {
        print("reponse /api/full", response)
    }
 }

希望这会有所帮助。

答案 2 :(得分: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.)

答案 3 :(得分:0)

这是我的解决方案:

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]

效果是从整个布料中选择这个格子图案中的黑色区域。

arbitary cut

例如,

test是一个2D数组。

D1D2是列和行中的索引列表。我们想要一些切割

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

但是,目前还不清楚,为什么test[D1,D2]无效。

答案 4 :(得分:0)

您的答案表明您正在使用numpy,因此您可以为此使用r_而不是构造范围。

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

已设计使用序列对多维数组进行索引,以work a bit differently使用切片进行索引。例如test[[0, 1, 2], [3, 4, 5]]将返回包含test[0, 3], test[1, 4], test[2, 5]的数组。这就是为什么您的答案中的test[D1, D2]不起作用。

如果您想使用一种更方便的语法,可以使类扩展ndarray,并使用一种用于处理索引的更改方法:

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

答案 5 :(得分:-2)

Concatenate是一种很棒的方式,或者你可以加入两个列表

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

mergedlist = list(set(part1 + part2))

这将创建一个合并列表,其中包含第一个列表中项目的浅表副本,后面是第二个列表中项目的浅表副本。

如果要进行深层复制,可以使用copy.deepcopy命令。