简体   繁体   English

给定索引列表,将任意维度的 numpy 切片到一维数组

[英]Slice numpy ndarry of arbitrary dimension to 1d array given a list of indices

I have a numpy ndarray arr and also indices , a list of indices specifying a particular entry.我有一个 numpy ndarray arrindices ,一个指定特定条目的索引列表。 For concreteness let's take:具体来说,让我们采取:

arr = np.arange(2*3*4).reshape((2,3,4))
indices= [1,0,3]

I have code to take 1d slices through arr observing all but one index n :我有代码通过arr观察除一个索引n之外的所有 1d 切片:

arr[:, indices[1], indices[2]]  # n = 0
arr[indices[0], :, indices[2]]  # n = 1
arr[indices[0], indices[1], :]  # n = 2

I would like to change my code to loop over n and support an arr of arbitrary dimension.我想更改我的代码以循环n并支持任意维度的arr

I've had a look at the indexing routines entry in the documentation and found information about slice() and np.s_() .我查看了文档中的 索引例程条目,并找到了有关slice()np.s_()的信息。 I was able to hack together something that works like what I want:我能够拼凑出我想要的东西:

def make_custom_slice(n, indices):
    s = list()
    for i, idx in enumerate(indices):
        if i == n:
            s.append(slice(None))
        else:
            s.append(slice(idx, idx+1))
    return tuple(s)


for n in range(arr.ndim):
    np.squeeze(arr[make_custom_slice(n, indices)])

Where np.squeeze is used to remove the axes of length 1. Without this, the array this produced has shape (arr.shape[n],1,1,...) rather than (arr.shape[n],) .其中np.squeeze用于删除长度为 1 的轴。没有这个,这个产生的数组具有形状(arr.shape[n],1,1,...)而不是(arr.shape[n],) .

Is there a more idiomatic way to accomplish this task?有没有更惯用的方法来完成这项任务?

Some improvements to the solution above (there may still be a one-liner or a more performant solution):对上述解决方案的一些改进(可能仍然存在单行或更高性能的解决方案):

def make_custom_slice(n, indices):
    s = indices.copy()
    s[n] = slice(None)
    return tuple(s)


for n in range(arr.ndim):
    print(arr[make_custom_slice(n, indices)])

An integer value idx can be used to replace the slice object slice(idx, idx+1) .一个 integer 值idx可用于替换切片 object slice(idx, idx+1) Because most indices are copied over directly, start with a copy of indices rather than building the list from scratch.因为大多数索引都是直接复制的,所以从索引的副本开始,而不是从头开始构建列表。

When built in this way, the result of arr[make_custom_slice(n, indices) has the expected dimension and np.squeeze is unnecessary.当以这种方式构建时, arr[make_custom_slice(n, indices)的结果具有预期的维度,并且np.squeeze是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM