简体   繁体   English

python:在给定维度索引的情况下提取多维数组的一个切片

[英]python: extracting one slice of a multidimensional array given the dimension index

I know how to take x[:,:,:,:,j,:] (which takes the jth slice of dimension 4). 我知道如何取x[:,:,:,:,j,:] (它采用第4维的第j个切片)。

Is there a way to do the same thing if the dimension is known at runtime, and is not a known constant? 如果维度在运行时已知,并且不是已知的常量,是否有办法做同样的事情?

One option to do so is to construct the slicing programatically: 这样做的一个选择是以编程方式构造切片:

slicing = (slice(None),) * 4 + (j,) + (slice(None),)

An alternative is to use numpy.take() or ndarray.take() : 另一种方法是使用numpy.take()ndarray.take()

>>> a = numpy.array([[1, 2], [3, 4]])
>>> a.take((1,), axis=0)
array([[3, 4]])
>>> a.take((1,), axis=1)
array([[2],
       [4]])

You can use the slice function and call it with the appropriate variable list during runtime as follows: 您可以使用slice函数并在运行时使用适当的变量列表调用它,如下所示:

# Store the variables that represent the slice in a list/tuple
# Make a slice with the unzipped tuple using the slice() command
# Use the slice on your array

Example: 例:

>>> from numpy import *
>>> a = (1, 2, 3)
>>> b = arange(27).reshape(3, 3, 3)
>>> s = slice(*a)
>>> b[s]
array([[[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])

This is the same as: 这与:

>>> b[1:2:3]
array([[[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])

Finally, the equivalent of not specifying anything between 2 : in the usual notation is to put None in those places in the tuple you create. 最后,相当于在通常的表示法中没有指定2 :之间的任何东西是将None放在你创建的元组中的那些位置。

If everything is decided at runtime, you could do: 如果一切都在运行时决定,你可以这样做:

# Define the data (this could be measured at runtime)
data_shape = (3, 5, 7, 11, 13)
print('data_shape = {}'.format(data_shape))

# Pick which index to slice from which dimension (could also be decided at runtime)
slice_dim = len(data_shape)/2
slice_index = data_shape[slice_dim]/2
print('slice_dim = {} (data_shape[{}] = {}), slice_index = {}'.format(slice_dim, slice_dim, data_shape[slice_dim], slice_index))

# Make a data set for testing
data = arange(product(data_shape)).reshape(*data_shape)

# Slice the data
s = [slice_index if a == slice_dim else slice(None) for a in range(len(data_shape))]
d = data[s]
print('shape(data[s]) = {}, s = {}'.format(shape(d), s))

Although this is longer than ndarray.take() , it will work if slice_index = None , as in the case where the array happens to have so few dimensions that you don't actually want to slice it (but you don't know you don't want to slice it ahead of time). 虽然这比ndarray.take()更长,但是如果slice_index = None ,它将起作用,就像数组恰好有这么少的尺寸而你实际上并不想要切片的那样(但你不认识你)不想提前切片)。

You can also use ellipsis to replace the repeating colons. 您还可以使用省略号来替换重复的冒号。 See an answer to How do you use the ellipsis slicing syntax in Python? 请参阅如何在Python中使用省略号切片语法答案 for an example. 举个例子。

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

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